Ticket #9206: 9206-r9084-raw-sql-docs.diff

File 9206-r9084-raw-sql-docs.diff, 4.9 KB (added by Richard Davies <richard.davies@…>, 7 years ago)

Improve documentation on raw SQL queries

  • docs/topics/db/models.txt

    727727Another common pattern is writing custom SQL statements in model methods and
    728 module-level methods. The object :class:`django.db.connection
    729 <django.db.backends.DatabaseWrapper>` represents the current database
    730 connection. To use it, call :meth:`connection.cursor()
    731 <django.db.backends.DatabaseWrapper.cursor>` to get a cursor object. Then, call
    732 ``cursor.execute(sql, [params])`` to execute the SQL and
    733 :meth:`cursor.fetchone() <django.db.backends.CursorWrapper.fetchone>` or
    734 :meth:`cursor.fetchall() <django.db.backends.CursorWrapper.fetchall>` to return
    735 the resulting rows. For example::
     728module-level methods. See :ref:`raw SQL <topic-db-sql>`.
    737     def my_custom_sql(self):
    738         from django.db import connection
    739         cursor = connection.cursor()
    740         cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    741         row = cursor.fetchone()
    742         return row
    744 :class:`connection <django.db.backends.DatabaseWrapper>` and :class:`cursor
    745 <django.db.backends.CursorWrapper>` mostly implement the standard Python
    746 DB-API -- see :pep:`249` -- with the addition of Django's :ref:`transaction
    747 handling <topics-db-transactions>`. If you're not familiar with the Python
    748 DB-API, note that the SQL statement in :meth:`cursor.execute()
    749 <django.db.backends.CursorWrapper.execute>` uses placeholders, ``"%s"``, rather
    750 than adding parameters directly within the SQL. If you use this technique, the
    751 underlying database library will automatically add quotes and escaping to your
    752 parameter(s) as necessary. (Also note that Django expects the ``"%s"``
    753 placeholder, *not* the ``"?"`` placeholder, which is used by the SQLite Python
    754 bindings. This is for the sake of consistency and sanity.)
    756 A final note: If all you want to do is a custom ``WHERE`` clause, you can use
    757 the :meth:`~QuerySet.extra` lookup method, which lets you add custom SQL to a
    758 query.
    760730.. _model-inheritance:
    762732Model inheritance
  • docs/topics/db/sql.txt

    66Feel free to write custom SQL statements in custom model methods and
    77module-level methods. The object ``django.db.connection`` represents the
    8 current database connection. To use it, call ``connection.cursor()`` to get a
     8current database connection, and ``django.db.transaction`` represents the
     9current database transaction. To use it, call ``connection.cursor()`` to get a
    910cursor object. Then, call ``cursor.execute(sql, [params])`` to execute the SQL
    1011and ``cursor.fetchone()`` or ``cursor.fetchall()`` to return the resulting
    11 rows. Example::
     12rows, followed by ``transaction.commit_unless_managed()`` to commit the
     13change. Example::
    1315    def my_custom_sql(self):
    14         from django.db import connection
     16        from django.db import connection, transaction
    1517        cursor = connection.cursor()
    1618        cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    1719        row = cursor.fetchone()
     20        cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
     21        transaction.commit_unless_managed()
    1822        return row
    2024``connection`` and ``cursor`` mostly implement the standard `Python DB-API`_
    3135use the ``where``, ``tables`` and ``params`` arguments to the standard lookup
     38Transaction handling
     41Django :ref:`transaction handling <topic-db-transactions>` offers a choice
     42of different behaviors, if you're using a database that supports
     45Raw SQL users should note that all their commands are actually always run
     46inside a transaction, even when using Django in auto-commit mode. As per the
     47standard `Python DB-API`, all database connections come wrapped inside a
     48transaction. In the default Django auto-commit mode, it simulates
     49auto-commit by regularly committing this underlying transaction, e.g. in
     52As a result, raw SQL users should call
     53``transaction.commit_unless_managed()`` after ``cursor.execute()``, just as
     54``model.save()`` does internally.
     56Raw SQL users with PostgreSQL should note that once a PostgreSQL raises an
     57exception, all subsequent SQL in the same transaction fails with the error
     58"current transaction is aborted, queries ignored until end of transaction
     59block". As a result, raw SQL users with PostgreSQL should additionally wrap
     60commands that may throw IntegrityError inside savepoints. Example::
     62    try:
     63        sid = transaction.savepoint()
     64        cursor.execute(XXX)
     65        transaction.savepoint_commit(sid)
     66    except IntegrityError:
     67        transaction.savepoint_rollback(sid)
     68        raise
    3470.. _Python DB-API: http://www.python.org/peps/pep-0249.html
Back to Top