summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/state.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2009-05-17 21:51:40 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2009-05-17 21:51:40 +0000
commit155466aad1c5ae4b43ed167a8b6e6013f0241370 (patch)
tree7c237401dd7f0ee68097bb3d0474dd9c33b80500 /lib/sqlalchemy/orm/state.py
parent2be867ffac8881a4a20ca5387063ed207ac876dc (diff)
downloadsqlalchemy-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.py24
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