summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-08-18 15:01:59 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-08-18 15:01:59 -0400
commit902e013ec127bbef29c3f609e8b8de835791b1d1 (patch)
tree4c54b6a7a621f2b2a3c6c4ef906130e173adc577
parent236db85f96e84fe099e63182bc4e67ceb65bd0d0 (diff)
downloadsqlalchemy-902e013ec127bbef29c3f609e8b8de835791b1d1.tar.gz
- add better notes to query.update(), most notably how to deal with a joined table
update, [ticket:2798]
-rw-r--r--doc/build/core/tutorial.rst2
-rw-r--r--lib/sqlalchemy/orm/query.py48
2 files changed, 38 insertions, 12 deletions
diff --git a/doc/build/core/tutorial.rst b/doc/build/core/tutorial.rst
index 0203248ae..b130f4d72 100644
--- a/doc/build/core/tutorial.rst
+++ b/doc/build/core/tutorial.rst
@@ -1593,6 +1593,8 @@ table, or the same table:
COMMIT
{stop}<sqlalchemy.engine.result.ResultProxy object at 0x...>
+.. _multi_table_updates:
+
Multiple Table Updates
----------------------
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index ace4c118e..94447fb12 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -2624,18 +2624,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.
"""