summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/dml.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-12-20 19:12:31 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2013-12-20 19:12:31 -0500
commit730b23239365c0392077626d04246e8a62e7f40d (patch)
treec933d81368b10c59a61e279d407dfb2b4dc1316c /lib/sqlalchemy/sql/dml.py
parent65bd6ec96602ab8b755b9bc25638957a09477de6 (diff)
downloadsqlalchemy-730b23239365c0392077626d04246e8a62e7f40d.tar.gz
- improve documentation for return_defaults() and returned_defaults. [ticket:2852]
Diffstat (limited to 'lib/sqlalchemy/sql/dml.py')
-rw-r--r--lib/sqlalchemy/sql/dml.py85
1 files changed, 59 insertions, 26 deletions
diff --git a/lib/sqlalchemy/sql/dml.py b/lib/sqlalchemy/sql/dml.py
index 83f4365d7..5f2eeabfe 100644
--- a/lib/sqlalchemy/sql/dml.py
+++ b/lib/sqlalchemy/sql/dml.py
@@ -75,12 +75,26 @@ class UpdateBase(HasPrefixes, Executable, ClauseElement):
@_generative
def returning(self, *cols):
- """Add a RETURNING or equivalent clause to this statement.
+ """Add a :term:`RETURNING` or equivalent clause to this statement.
- The given list of columns represent columns within the table that is
- the target of the INSERT, UPDATE, or DELETE. Each element can be any
- column expression. :class:`~sqlalchemy.schema.Table` objects will be
- expanded into their individual columns.
+ e.g.::
+
+ stmt = table.update().\\
+ where(table.c.data == 'value').\\
+ values(status='X').\\
+ returning(table.c.server_flag, table.c.updated_timestamp)
+
+ for server_flag, updated_timestamp in connection.execute(stmt):
+ print(server_flag, updated_timestamp)
+
+ The given collection of column expressions should be derived from
+ the table that is
+ the target of the INSERT, UPDATE, or DELETE. While :class:`.Column`
+ objects are typical, the elements can also be expressions::
+
+ stmt = table.insert().returning(
+ (table.c.first_name + " " + table.c.last_name).label('fullname')
+ )
Upon compilation, a RETURNING clause, or database equivalent,
will be rendered within the statement. For INSERT and UPDATE,
@@ -89,7 +103,7 @@ class UpdateBase(HasPrefixes, Executable, ClauseElement):
Upon execution, the values of the columns to be returned
are made available via the result set and can be iterated
- using ``fetchone()`` and similar. For DBAPIs which do not
+ using :meth:`.ResultProxy.fetchone` and similar. For DBAPIs which do not
natively support returning values (i.e. cx_oracle),
SQLAlchemy will approximate this behavior at the result level
so that a reasonable amount of behavioral neutrality is
@@ -106,7 +120,10 @@ class UpdateBase(HasPrefixes, Executable, ClauseElement):
.. seealso::
- :meth:`.ValuesBase.return_defaults`
+ :meth:`.ValuesBase.return_defaults` - an alternative method tailored
+ towards efficient fetching of server-side defaults and triggers
+ for single-row INSERTs or UPDATEs.
+
"""
self._returning = cols
@@ -310,40 +327,56 @@ class ValuesBase(UpdateBase):
@_generative
def return_defaults(self, *cols):
- """If available, make use of a RETURNING clause for the purpose
+ """Make use of a :term:`RETURNING` clause for the purpose
of fetching server-side expressions and defaults.
+ E.g.::
+
+ stmt = table.insert().values(data='newdata').return_defaults()
+
+ result = connection.execute(stmt)
+
+ server_created_at = result.returned_defaults['created_at']
+
When used against a backend that supports RETURNING, all column
values generated by SQL expression or server-side-default will be added
- to any existing RETURNING clause, excluding one that is specified
- by the :meth:`.UpdateBase.returning` method. The column values
+ to any existing RETURNING clause, provided that
+ :meth:`.UpdateBase.returning` is not used simultaneously. The column values
will then be available on the result using the
- :meth:`.ResultProxy.server_returned_defaults` method as a
- dictionary, referring to values keyed to the :meth:`.Column` object
+ :attr:`.ResultProxy.returned_defaults` accessor as a
+ dictionary, referring to values keyed to the :class:`.Column` object
as well as its ``.key``.
This method differs from :meth:`.UpdateBase.returning` in these ways:
- 1. It is compatible with any backend. Backends that don't support
- RETURNING will skip the usage of the feature, rather than raising
- an exception. The return value of :attr:`.ResultProxy.returned_defaults`
- will be ``None``
+ 1. :meth:`.ValuesBase.return_defaults` is only intended for use with
+ an INSERT or an UPDATE statement that matches exactly one row.
+ While the RETURNING construct in the general sense supports multiple
+ rows for a multi-row UPDATE or DELETE statement, or for special
+ cases of INSERT that return multiple rows (e.g. INSERT from SELECT,
+ multi-valued VALUES clause), :meth:`.ValuesBase.return_defaults`
+ is intended only
+ for an "ORM-style" single-row INSERT/UPDATE statement. The row
+ returned by the statement is also consumed implcitly when
+ :meth:`.ValuesBase.return_defaults` is used. By contrast,
+ :meth:`.UpdateBase.returning` leaves the RETURNING result-set intact
+ with a collection of any number of rows.
2. It is compatible with the existing logic to fetch auto-generated
primary key values, also known as "implicit returning". Backends that
support RETURNING will automatically make use of RETURNING in order
to fetch the value of newly generated primary keys; while the
:meth:`.UpdateBase.returning` method circumvents this behavior,
- :meth:`.UpdateBase.return_defaults` leaves it intact.
+ :meth:`.ValuesBase.return_defaults` leaves it intact.
+
+ 3. It can be called against any backend. Backends that don't support
+ RETURNING will skip the usage of the feature, rather than raising
+ an exception. The return value of :attr:`.ResultProxy.returned_defaults`
+ will be ``None``
- 3. :meth:`.UpdateBase.returning` leaves the cursor's rows ready for
- fetching using methods like :meth:`.ResultProxy.fetchone`, whereas
- :meth:`.ValuesBase.return_defaults` fetches the row internally.
- While all DBAPI backends observed so far seem to only support
- RETURNING with single-row executions,
- technically :meth:`.UpdateBase.returning` would support a backend
- that can deliver multiple RETURNING rows as well. However
- :meth:`.ValuesBase.return_defaults` is single-row by definition.
+ :meth:`.ValuesBase.return_defaults` is used by the ORM to provide
+ an efficient implementation for the ``eager_defaults`` feature of
+ :func:`.mapper`.
:param cols: optional list of column key names or :class:`.Column`
objects. If omitted, all column expressions evaulated on the server
@@ -355,7 +388,7 @@ class ValuesBase(UpdateBase):
:meth:`.UpdateBase.returning`
- :meth:`.ResultProxy.returned_defaults`
+ :attr:`.ResultProxy.returned_defaults`
"""
self._return_defaults = cols or True