diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-01-04 14:09:32 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-01-04 14:09:32 -0500 |
commit | 5811276bb7515af3418a6d20f5213d658e320121 (patch) | |
tree | d595e9c2659abda8f8eee65bbc74fe038aa4c49f /lib/sqlalchemy | |
parent | 435aaff20effbc914bbb4d19f177df3c1f5f15ab (diff) | |
download | sqlalchemy-5811276bb7515af3418a6d20f5213d658e320121.tar.gz |
Check for object was expunged before restoring after pk switch + rollback
Fixed bug where an object that is expunged during a rollback of
a nested or subtransaction which also had its primary key mutated
would not be correctly removed from the session, causing subsequent
issues in using the session.
Change-Id: I57e2888902015d67ee11857e44382818f1d2f8bc
Fixes: #4151
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r-- | lib/sqlalchemy/orm/session.py | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index bd0bf9197..6c91df866 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -339,14 +339,20 @@ class SessionTransaction(object): """ assert self._is_transaction_boundary - self.session._expunge_states( - set(self._new).union(self.session._new), - to_transient=True) + to_expunge = set(self._new).union(self.session._new) + self.session._expunge_states(to_expunge, to_transient=True) for s, (oldkey, newkey) in self._key_switches.items(): + # we probably can do this conditionally based on + # if we expunged or not, but safe_discard does that anyway self.session.identity_map.safe_discard(s) + + # restore the old key s.key = oldkey - self.session.identity_map.replace(s) + + # now restore the object, but only if we didn't expunge + if s not in to_expunge: + self.session.identity_map.replace(s) for s in set(self._deleted).union(self.session._deleted): self.session._update_impl(s, revert_deletion=True) |