]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commit
process bulk_update_tuples before cache key or compilation
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 19 Oct 2021 18:07:32 +0000 (14:07 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 19 Oct 2021 19:10:14 +0000 (15:10 -0400)
commit18b4a3437a60fbfa0c25287d9a3b83d7c9d4f762
treec9c5758b40c29cf67fe38674f0e2893912dda937
parente86c40b9254f25ca9a765622f911c6dbd4bd2f1f
process bulk_update_tuples before cache key or compilation

Fixed regression where the use of a :class:`_orm.hybrid_property` attribute
or a mapped :func:`_orm.composite` attribute as a key passed to the
:meth:`_dml.Update.values` method for an ORM-enabled :class:`_dml.Update`
statement, as well as when using it via the legacy
:meth:`_orm.Query.update` method, would be processed for incoming
ORM/hybrid/composite values within the compilation stage of the UPDATE
statement, which meant that in those cases where caching occurred,
subsequent invocations of the same statement would no longer receive the
correct values. This would include not only hybrids that use the
:meth:`_orm.hybrid_property.update_expression` method, but any use of a
plain hybrid attribute as well. For composites, the issue instead caused a
non-repeatable cache key to be generated, which would break caching and
could fill up the statement cache with repeated statements.

The :class:`_dml.Update` construct now handles the processing of key/value
pairs passed to :meth:`_dml.Update.values` and
:meth:`_dml.Update.ordered_values` up front when the construct is first
generated, before the cache key has been generated so that the key/value
pairs are processed each time, and so that the cache key is generated
against the individual column/value pairs that will ultimately be
used in the statement.

Fixes: #7209
Change-Id: I08f248d1d60ea9690b014c21439b775d951fb9e5
12 files changed:
doc/build/changelog/unreleased_14/7209.rst [new file with mode: 0644]
lib/sqlalchemy/ext/hybrid.py
lib/sqlalchemy/orm/persistence.py
lib/sqlalchemy/sql/base.py
lib/sqlalchemy/sql/dml.py
lib/sqlalchemy/sql/elements.py
test/ext/test_hybrid.py
test/orm/test_cache_key.py
test/orm/test_composites.py
test/orm/test_update_delete.py
test/requirements.py
test/sql/test_update.py