2008-08-24 06:25:40 +08:00
|
|
|
.. _topics-db-sql:
|
|
|
|
|
|
|
|
Performing raw SQL queries
|
|
|
|
==========================
|
|
|
|
|
|
|
|
Feel free to write custom SQL statements in custom model methods and
|
|
|
|
module-level methods. The object ``django.db.connection`` represents the
|
2009-05-02 15:40:25 +08:00
|
|
|
current database connection, and ``django.db.transaction`` represents the
|
|
|
|
current database transaction. To use the database connection, call
|
|
|
|
``connection.cursor()`` to get a cursor object. Then, call
|
|
|
|
``cursor.execute(sql, [params])`` to execute the SQL and ``cursor.fetchone()``
|
|
|
|
or ``cursor.fetchall()`` to return the resulting rows. After performing a data
|
|
|
|
changing operation, you should then call
|
|
|
|
``transaction.commit_unless_managed()`` to ensure your changes are committed
|
|
|
|
to the database. If your query is purely a data retrieval operation, no commit
|
|
|
|
is required. For example::
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
def my_custom_sql(self):
|
2009-05-02 15:40:25 +08:00
|
|
|
from django.db import connection, transaction
|
2008-08-24 06:25:40 +08:00
|
|
|
cursor = connection.cursor()
|
2009-05-02 15:40:25 +08:00
|
|
|
|
|
|
|
# Data modifying operation - commit required
|
|
|
|
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
|
|
|
|
transaction.commit_unless_managed()
|
|
|
|
|
|
|
|
# Data retrieval operation - no commit required
|
2008-08-24 06:25:40 +08:00
|
|
|
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
|
|
|
|
row = cursor.fetchone()
|
2009-05-02 15:40:25 +08:00
|
|
|
|
2008-08-24 06:25:40 +08:00
|
|
|
return row
|
|
|
|
|
|
|
|
``connection`` and ``cursor`` mostly implement the standard `Python DB-API`_
|
|
|
|
(except when it comes to :ref:`transaction handling <topics-db-transactions>`).
|
|
|
|
If you're not familiar with the Python DB-API, note that the SQL statement in
|
|
|
|
``cursor.execute()`` uses placeholders, ``"%s"``, rather than adding parameters
|
|
|
|
directly within the SQL. If you use this technique, the underlying database
|
|
|
|
library will automatically add quotes and escaping to your parameter(s) as
|
|
|
|
necessary. (Also note that Django expects the ``"%s"`` placeholder, *not* the
|
|
|
|
``"?"`` placeholder, which is used by the SQLite Python bindings. This is for
|
|
|
|
the sake of consistency and sanity.)
|
|
|
|
|
|
|
|
A final note: If all you want to do is a custom ``WHERE`` clause, you can just
|
|
|
|
use the ``where``, ``tables`` and ``params`` arguments to the standard lookup
|
2009-05-02 15:40:25 +08:00
|
|
|
API.
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
.. _Python DB-API: http://www.python.org/peps/pep-0249.html
|
|
|
|
|