diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-04 18:32:38 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-04 18:32:38 -0400 |
| commit | e07f4b9837455971ce95a1f306dc80a3f716ed64 (patch) | |
| tree | d992c22193dc99526fa82c3a2024579690ca3724 /lib/sqlalchemy/orm/state.py | |
| parent | 79f26dbff98a3e5625c94fbea5bfb35a2d7016cf (diff) | |
| download | sqlalchemy-e07f4b9837455971ce95a1f306dc80a3f716ed64.tar.gz | |
- [feature] A warning is emitted when a reference
to an instrumented collection is no longer
associated with the parent class due to
expiration/attribute refresh/collection
replacement, but an append
or remove operation is received on the
now-detached collection. [ticket:2476]
Diffstat (limited to 'lib/sqlalchemy/orm/state.py')
| -rw-r--r-- | lib/sqlalchemy/orm/state.py | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 1c7fc2c41..9d17fa344 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -288,7 +288,9 @@ class InstanceState(interfaces._InspectionAttr): """Remove the given attribute and any callables associated with it.""" - dict_.pop(key, None) + old = dict_.pop(key, None) + if old is not None and self.manager[key].impl.collection: + self.manager[key].impl._invalidate_collection(old) self.callables.pop(key, None) def _expire_attribute_pre_commit(self, dict_, key): @@ -296,6 +298,8 @@ class InstanceState(interfaces._InspectionAttr): The additional bookkeeping is finished up in commit_all(). + Should only be called for scalar attributes. + This method is actually called a lot with joined-table loading, when the second table isn't present in the result. @@ -307,7 +311,9 @@ class InstanceState(interfaces._InspectionAttr): """Remove the given attribute and set the given callable as a loader.""" - dict_.pop(key, None) + old = dict_.pop(key, None) + if old is not None and self.manager[key].impl.collection: + self.manager[key].impl._invalidate_collection(old) self.callables[key] = callable_ def _expire(self, dict_, modified_set): @@ -331,7 +337,9 @@ class InstanceState(interfaces._InspectionAttr): if impl.accepts_scalar_loader and \ (impl.expire_missing or key in dict_): self.callables[key] = self - dict_.pop(key, None) + old = dict_.pop(key, None) + if impl.collection and old is not None: + impl._invalidate_collection(old) self.manager.dispatch.expire(self, None) @@ -342,7 +350,9 @@ class InstanceState(interfaces._InspectionAttr): impl = self.manager[key].impl if impl.accepts_scalar_loader: self.callables[key] = self - dict_.pop(key, None) + old = dict_.pop(key, None) + if impl.collection and old is not None: + impl._invalidate_collection(old) self.committed_state.pop(key, None) if pending: |
