diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-05-17 21:51:40 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-05-17 21:51:40 +0000 |
commit | 155466aad1c5ae4b43ed167a8b6e6013f0241370 (patch) | |
tree | 7c237401dd7f0ee68097bb3d0474dd9c33b80500 /lib/sqlalchemy/orm/state.py | |
parent | 2be867ffac8881a4a20ca5387063ed207ac876dc (diff) | |
download | sqlalchemy-155466aad1c5ae4b43ed167a8b6e6013f0241370.tar.gz |
- Removed all* O(N) scanning behavior from the flush() process,
i.e. operations that were scanning the full session,
including an extremely expensive one that was erroneously
assuming primary key values were changing when this
was not the case.
* one edge case remains which may invoke a full scan,
if an existing primary key attribute is modified
to a new value.
Diffstat (limited to 'lib/sqlalchemy/orm/state.py')
-rw-r--r-- | lib/sqlalchemy/orm/state.py | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index c99dfe73c..1b73a1bb6 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -193,12 +193,20 @@ class InstanceState(object): key for key in self.manager.iterkeys() if key not in self.committed_state and key not in self.dict) - def expire_attributes(self, attribute_names): + def expire_attributes(self, attribute_names, instance_dict=None): self.expired_attributes = set(self.expired_attributes) if attribute_names is None: attribute_names = self.manager.keys() self.expired = True + if self.modified: + if not instance_dict: + instance_dict = self._instance_dict() + if instance_dict: + instance_dict._modified.discard(self) + else: + instance_dict._modified.discard(self) + self.modified = False filter_deferred = True else: @@ -248,13 +256,14 @@ class InstanceState(object): if needs_committed: self.committed_state[attr.key] = previous + if not self.modified: + instance_dict = self._instance_dict() + if instance_dict: + instance_dict._modified.add(self) + self.modified = True self._strong_obj = self.obj() - instance_dict = self._instance_dict() - if instance_dict: - instance_dict.modified = True - def commit(self, dict_, keys): """Commit attributes. @@ -279,7 +288,7 @@ class InstanceState(object): self.expired_attributes.remove(key) self.callables.pop(key, None) - def commit_all(self, dict_): + def commit_all(self, dict_, instance_dict=None): """commit all attributes unconditionally. This is used after a flush() or a full load/refresh @@ -308,6 +317,9 @@ class InstanceState(object): if key in dict_: self.manager[key].impl.commit_to_state(self, dict_, self.committed_state) + if instance_dict and self.modified: + instance_dict._modified.discard(self) + self.modified = self.expired = False self._strong_obj = None |