]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- add better notes to query.update(), most notably how to deal with a joined table
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 18 Aug 2013 19:01:59 +0000 (15:01 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 18 Aug 2013 19:02:40 +0000 (15:02 -0400)
update, [ticket:2798]

doc/build/core/tutorial.rst
lib/sqlalchemy/orm/query.py

index 0203248aee84edd7ce18512b893791b9cc73d029..b130f4d72142f8a966fb8017acab5c4f9562f0dd 100644 (file)
@@ -1593,6 +1593,8 @@ table, or the same table:
     COMMIT
     {stop}<sqlalchemy.engine.result.ResultProxy object at 0x...>
 
+.. _multi_table_updates:
+
 Multiple Table Updates
 ----------------------
 
index 1743aa59906b990ab338f1b6ca1ab9c56ed6aa5e..564146ed01ce63048caf7b4dbccbc7986959e713 100644 (file)
@@ -2619,18 +2619,42 @@ class Query(object):
 
         Returns the number of rows matched by the update.
 
-        The method does *not* offer in-Python cascading of relationships - it
-        is assumed that ON UPDATE CASCADE is configured for any foreign key
-        references which require it.
-
-        The Session needs to be expired (occurs automatically after commit(),
-        or call expire_all()) in order for the state of dependent objects
-        subject foreign key cascade to be correctly represented.
-
-        Note that the :meth:`.MapperEvents.before_update` and
-        :meth:`.MapperEvents.after_update`
-        events are **not** invoked from this method.  It instead
-        invokes :meth:`.SessionEvents.after_bulk_update`.
+        This method has several key caveats:
+
+        * The method does **not** offer in-Python cascading of relationships - it
+          is assumed that ON UPDATE CASCADE is configured for any foreign key
+          references which require it, otherwise the database may emit an
+          integrity violation if foreign key references are being enforced.
+
+          After the UPDATE, dependent objects in the :class:`.Session` which
+          were impacted by an ON UPDATE CASCADE may not contain the current
+          state; this issue is resolved once the :class:`.Session` is expired,
+          which normally occurs upon :meth:`.Session.commit` or can be forced
+          by using :meth:`.Session.expire_all`.
+
+        * As of 0.8, this method will support multiple table updates, as detailed
+          in :ref:`multi_table_updates`, and this behavior does extend to support
+          updates of joined-inheritance and other multiple table mappings.  However,
+          the **join condition of an inheritance mapper is currently not
+          automatically rendered**.
+          Care must be taken in any multiple-table update to explicitly include
+          the joining condition between those tables, even in mappings where
+          this is normally automatic.
+          E.g. if a class ``Engineer`` subclasses ``Employee``, an UPDATE of the
+          ``Engineer`` local table using criteria against the ``Employee``
+          local table might look like::
+
+                session.query(Engineer).\\
+                    filter(Engineer.id == Employee.id).\\
+                    filter(Employee.name == 'dilbert').\\
+                    update({"engineer_type": "programmer"})
+
+
+        * The :meth:`.MapperEvents.before_update` and
+          :meth:`.MapperEvents.after_update`
+          events are **not** invoked from this method.  Instead, the
+          :meth:`.SessionEvents.after_bulk_update` method is provided to act
+          upon a mass UPDATE of entity rows.
 
         """