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

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

Updated for Malcolm's comments

  • docs/topics/db/models.txt

     
    752752--------------------
    753753
    754754Another common pattern is writing custom SQL statements in model methods and
    755 module-level methods. The object :class:`django.db.connection
    756 <django.db.backends.DatabaseWrapper>` represents the current database
    757 connection. To use it, call :meth:`connection.cursor()
    758 <django.db.backends.DatabaseWrapper.cursor>` to get a cursor object. Then, call
    759 ``cursor.execute(sql, [params])`` to execute the SQL and
    760 :meth:`cursor.fetchone() <django.db.backends.CursorWrapper.fetchone>` or
    761 :meth:`cursor.fetchall() <django.db.backends.CursorWrapper.fetchall>` to return
    762 the resulting rows. For example::
     755module-level methods. See :ref:`raw SQL <topic-db-sql>`.
    763756
    764     def my_custom_sql(self):
    765         from django.db import connection
    766         cursor = connection.cursor()
    767         cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    768         row = cursor.fetchone()
    769         return row
    770 
    771 :class:`connection <django.db.backends.DatabaseWrapper>` and :class:`cursor
    772 <django.db.backends.CursorWrapper>` mostly implement the standard Python
    773 DB-API -- see :pep:`249` -- with the addition of Django's :ref:`transaction
    774 handling <topics-db-transactions>`. If you're not familiar with the Python
    775 DB-API, note that the SQL statement in :meth:`cursor.execute()
    776 <django.db.backends.CursorWrapper.execute>` uses placeholders, ``"%s"``, rather
    777 than adding parameters directly within the SQL. If you use this technique, the
    778 underlying database library will automatically add quotes and escaping to your
    779 parameter(s) as necessary. (Also note that Django expects the ``"%s"``
    780 placeholder, *not* the ``"?"`` placeholder, which is used by the SQLite Python
    781 bindings. This is for the sake of consistency and sanity.)
    782 
    783 A final note: If all you want to do is a custom ``WHERE`` clause, you can use
    784 the :meth:`~QuerySet.extra` lookup method, which lets you add custom SQL to a
    785 query.
    786 
    787757.. _model-inheritance:
    788758
    789759Model inheritance
  • docs/topics/db/transactions.txt

     
    1010Django's default transaction behavior
    1111=====================================
    1212
    13 Django's default behavior is to commit automatically when any built-in,
    14 data-altering model function is called. For example, if you call
    15 ``model.save()`` or ``model.delete()``, the change will be committed
    16 immediately.
     13Django's default behavior is to run with an open transaction which it
     14commits automatically when any built-in, data-altering model function is
     15called. For example, if you call ``model.save()`` or ``model.delete()``, the
     16change will be committed immediately.
    1717
    1818This is much like the auto-commit setting for most databases. As soon as you
    1919perform an action that needs to write to the database, Django produces the
     
    165165handle transactions as explained in this document.
    166166
    167167.. _information on MySQL transactions: http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactions.html
     168
     169Transactions and savepoints in PostgreSQL
     170=========================================
     171
     172If you're using PostgreSQL 8, then be aware that once PostgreSQL raises an
     173exception, all subsequent SQL in the same transaction fails with the error
     174"current transaction is aborted, queries ignored until end of transaction
     175block". Whilst simple use of save() is unlikely to raise an exception in
     176PostgreSQL, there are many more advanced usage patterns which might: e.g.
     177save with unique fields, save with force_insert/force_update, custom SQL.
     178
     179In any of these cases, you can wrap the command which may throw
     180IntegrityError inside savepoints, which will then allow subsequent commands
     181to proceed. Example::
     182
     183    try:
     184      sid = transaction.savepoint()
     185      x.save()
     186      transaction.savepoint_commit(sid)
     187    except IntegrityError:
     188      transaction.savepoint_rollback(sid)
     189      raise
     190
     191Transactions and autocommit in PostgreSQL
     192=========================================
     193
     194By default, Django starts a transaction when a database connection is first
     195used and regularly commits, as above. The PostgreSQL backends normally
     196operate the same as any other Django backend in this respect, but can
     197additionally support database-level :ref:`autocommit mode <ref-databases>`
     198with no constantly open transaction.
  • docs/topics/db/sql.txt

     
    55
    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. ``transaction.commit_unless_managed()`` is needed after
     13data-changing operations but not after pure selects, etc. Example::
    1214
    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
    1923
    2024``connection`` and ``cursor`` mostly implement the standard `Python DB-API`_
Back to Top