| 9 | .. note:: |
| 10 | |
| 11 | If all you want to do is a custom ``WHERE`` clause, the Query API supports |
| 12 | the ``where``, ``tables`` and ``params`` arguments using the |
| 13 | :ref:`extra modifier <querysets-extra-modifier>`. |
| 14 | |
| 15 | The object ``django.db.connection`` represents the current database |
| 16 | connection. To use it, call ``connection.cursor()`` to get a cursor object. |
| 17 | Then, call ``cursor.execute(sql, [params])`` to execute the SQL and |
| 18 | ``cursor.fetchone()`` or ``cursor.fetchall()`` to return the resulting rows. |
| 19 | The ``connection`` and ``cursor`` objects mostly implement the standard |
| 20 | `Python DB-API`_. For example:: |
| 21 | |
20 | | ``connection`` and ``cursor`` mostly implement the standard `Python DB-API`_ |
21 | | (except when it comes to :ref:`transaction handling <topics-db-transactions>`). |
22 | | If you're not familiar with the Python DB-API, note that the SQL statement in |
23 | | ``cursor.execute()`` uses placeholders, ``"%s"``, rather than adding parameters |
24 | | directly within the SQL. If you use this technique, the underlying database |
25 | | library will automatically add quotes and escaping to your parameter(s) as |
26 | | necessary. (Also note that Django expects the ``"%s"`` placeholder, *not* the |
27 | | ``"?"`` placeholder, which is used by the SQLite Python bindings. This is for |
28 | | the sake of consistency and sanity.) |
| 29 | When using cursor ``cursor.execute()`` you should use placeholders rather |
| 30 | than putting the parameters directly within the SQL. Doing this will let the |
| 31 | underlying database library automatically add quotes and escape to your |
| 32 | parameters as necessary. For the sake of consistency and sanity, Django |
| 33 | expects the ``"%s"`` placeholder, *not* the ``"?"`` placeholder, which is used |
| 34 | by the SQLite Python bindings. |
30 | | A final note: If all you want to do is a custom ``WHERE`` clause, you can just |
31 | | use the ``where``, ``tables`` and ``params`` arguments to the standard lookup |
32 | | API. |
| 36 | A major difference from the Python DB-API is the transaction handling. |
| 37 | Automatic transaction management (which is enabled by default) will not work |
| 38 | for raw SQL queries that modify the database since Django has no way of |
| 39 | detecting the changes. You will need to commit the transaction yourself. |
| 40 | A simple way to do this is to use Django's ``transaction.commit_manually`` |
| 41 | decorator:: |