diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-08-18 15:01:59 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-08-18 15:01:59 -0400 |
commit | 902e013ec127bbef29c3f609e8b8de835791b1d1 (patch) | |
tree | 4c54b6a7a621f2b2a3c6c4ef906130e173adc577 | |
parent | 236db85f96e84fe099e63182bc4e67ceb65bd0d0 (diff) | |
download | sqlalchemy-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.rst | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/query.py | 48 |
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. """ |