]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- improve documentation for return_defaults() and returned_defaults. [ticket:2852]
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 21 Dec 2013 00:12:31 +0000 (19:12 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 21 Dec 2013 00:12:31 +0000 (19:12 -0500)
lib/sqlalchemy/engine/result.py
lib/sqlalchemy/sql/dml.py

index 93c7d3b6bfa812ec68c6b9f33b9addb3bbd9576e..3a613ef5a055424433e735273a40343b900ff116 100644 (file)
@@ -627,10 +627,18 @@ class ResultProxy(object):
     @property
     def returned_defaults(self):
         """Return the values of default columns that were fetched using
-        the ``returned_defaults`` feature.
+        the :meth:`.ValuesBase.return_defaults` feature.
+
+        The value is an instance of :class:`.RowProxy`, or ``None``
+        if :meth:`.ValuesBase.return_defaults` was not used or if the
+        backend does not support RETURNING.
 
         .. versionadded:: 0.9.0
 
+        .. seealso::
+
+            :meth:`.ValuesBase.return_defaults`
+
         """
         return self.context.returned_defaults
 
index 83f4365d7e956b21213ad09e8833affabca5a90f..5f2eeabfe0354ab40e02331056cd4462a211a436 100644 (file)
@@ -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