Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

[1.0.X] Fixed #9919 -- Added note on the need to mark transactions as…

… dirty when using raw SQL.

Merge of r11022 from trunk.

  • Loading branch information...
commit 40bcd34fab32d112645fcdaecb1b92388094287b 1 parent e63e0bb
@freakboy3742 freakboy3742 authored
Showing with 46 additions and 2 deletions.
  1. +2 −0  docs/ref/models/querysets.txt
  2. +44 −2 docs/topics/db/sql.txt
2  docs/ref/models/querysets.txt
@@ -566,6 +566,8 @@ call, since they are conflicting options.
Both the ``depth`` argument and the ability to specify field names in the call
to ``select_related()`` are new in Django version 1.0.
+.. _extra:
``extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)``
46 docs/topics/db/sql.txt
@@ -29,6 +29,45 @@ is required. For example::
return row
+.. _transactions-and-raw-sql:
+Transactions and raw SQL
+If you are using transaction decorators (such as ``commit_on_success``) to
+wrap your views and provide transaction control, you don't have to make a
+manual call to ``transaction.commit_unless_managed()`` -- you can manually
+commit if you want to, but you aren't required to, since the decorator will
+commit for you. However, if you don't manually commit your changes, you will
+need to manually mark the transaction as dirty, using
+ @commit_on_success
+ def my_custom_sql_view(request, value):
+ from django.db import connection, transaction
+ cursor = connection.cursor()
+ # Data modifying operation
+ cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [value])
+ # Since we modified data, mark the transaction as dirty
+ transaction.set_dirty()
+ # Data retrieval operation. This doesn't dirty the transaction,
+ # so no call to set_dirty() is required.
+ cursor.execute("SELECT foo FROM bar WHERE baz = %s", [value])
+ row = cursor.fetchone()
+ return render_to_response('template.html', {'row': row})
+The call to ``set_dirty()`` is made automatically when you use the Django ORM
+to make data modifying database calls. However, when you use raw SQL, Django
+has no way of knowing if your SQL modifies data or not. The manual call to
+``set_dirty()`` ensures that Django knows that there are modifications that
+must be committed.
+Connections and cursors
``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
@@ -39,9 +78,12 @@ 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.)
+An easier option?
-use the ``where``, ``tables`` and ``params`` arguments to the standard lookup
+:ref:`extra clause <extra>` in the standard queryset API.
.. _Python DB-API:

0 comments on commit 40bcd34

Please sign in to comment.
Something went wrong with that request. Please try again.