diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-20 19:12:31 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-20 19:12:31 -0500 |
commit | 730b23239365c0392077626d04246e8a62e7f40d (patch) | |
tree | c933d81368b10c59a61e279d407dfb2b4dc1316c /lib/sqlalchemy/sql/dml.py | |
parent | 65bd6ec96602ab8b755b9bc25638957a09477de6 (diff) | |
download | sqlalchemy-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.py | 85 |
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 |