]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commit
Fix ORM UPDATE..RETURNING cache adaptation with synchronize_session=fetch
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 18 Jul 2026 15:59:14 +0000 (11:59 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 18 Jul 2026 19:55:18 +0000 (15:55 -0400)
commitbd0da4263052b4571f3b16eda3552e134b9b1689
tree5f42bc22dc11405b2d016e6e17f9719e6e1c3646
parent16177b8c73e492e5adaad8f51095f9981831da41
Fix ORM UPDATE..RETURNING cache adaptation with synchronize_session=fetch

Fixed result-metadata corruption affecting ORM-enabled UPDATE statements
that use .returning() together with synchronize_session="fetch".  In this
configuration the RETURNING clause is rendered in mapper/table column order
rather than the user-requested .returning() order; on a compiled-cache hit,
the cursor result metadata was positionally adapted against the cached
statement's user-requested column order, causing column values to be
returned under the wrong keys (e.g. row[T.a] returning T.b's value).

The mis-adaptation was frequently masked by cached row-getter functions
produced by a prior, correctly-adapted execution, so the wrong values
surfaced most reliably under concurrent execution racing on the shared
compiled cache.  The fix disables result-set adapt_to_context for this
path, mirroring the ORM INSERT and ORM SELECT load paths, since the cached
keymap already carries the correct Column objects.

ORM DELETE statements are not affected: DELETE does not pass through
crud._get_crud_params() and therefore retains the user-requested RETURNING
order; a non-regression DELETE case is included in the test.

Fixes: #13439
Change-Id: If58e93a0bb3220dc5637bc7bcf346d2177529d6d
doc/build/changelog/unreleased_20/13439.rst [new file with mode: 0644]
lib/sqlalchemy/orm/bulk_persistence.py
test/orm/dml/test_orm_upd_del_assorted.py