diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-10-01 18:04:46 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-10-04 14:38:21 -0400 |
| commit | e7e0757efe042b8343ef44d4f61a33cdbc072ff3 (patch) | |
| tree | de1ec0739f872c80d1cb3c617b28c46e17471b71 /lib/sqlalchemy/orm/identity.py | |
| parent | 71e463506217e3acc379a3f459e68a81792a0aac (diff) | |
| download | sqlalchemy-e7e0757efe042b8343ef44d4f61a33cdbc072ff3.tar.gz | |
disallow adding to identity map that's been discarded
Fixed bug where iterating a :class:`.Result` from a :class:`_orm.Session`
after that :class:`_orm.Session` were closed would partially attach objects
to that session in an essentially invalid state. It now raises an exception
with a link to new documentation if an **un-buffered** result is iterated
from a :class:`_orm.Session` that was closed or otherwise had the
:meth:`_orm.Session.expunge_all` method called after that :class:`.Result`
was generated. The "prebuffer_rows" execution option, as is used by the
asyncio extension, may be used to produce a :class:`.Result` where the ORM
objects are prebuffered, and in this case iterating the result will produce
a series of detached objects.
Fixes: #7128
Change-Id: I59f0ae32a83a64587937741b80f31ff825bbb574
Diffstat (limited to 'lib/sqlalchemy/orm/identity.py')
| -rw-r--r-- | lib/sqlalchemy/orm/identity.py | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py index 7eec4fd8d..6aea0d185 100644 --- a/lib/sqlalchemy/orm/identity.py +++ b/lib/sqlalchemy/orm/identity.py @@ -18,6 +18,9 @@ class IdentityMap(object): self._modified = set() self._wr = weakref.ref(self) + def _kill(self): + self._add_unpresent = _killed + def keys(self): return self._dict.keys() @@ -238,3 +241,14 @@ class WeakInstanceDict(IdentityMap): if st is state: self._dict.pop(state.key, None) self._manage_removed_state(state) + + +def _killed(state, key): + # external function to avoid creating cycles when assigned to + # the IdentityMap + raise sa_exc.InvalidRequestError( + "Object %s cannot be converted to 'persistent' state, as this " + "identity map is no longer valid. Has the owning Session " + "been closed?" % orm_util.state_str(state), + code="lkrp", + ) |
