summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/dependency.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-07-07 12:01:02 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2010-07-07 12:01:02 -0400
commit91ad6902c524f7d113dfd568288c0a5240ba9499 (patch)
tree06c915ef8ef96cf3167a44c7424e73535a834373 /lib/sqlalchemy/orm/dependency.py
parent406cedbeefb992247750ae25eb380ea40afb4a2c (diff)
downloadsqlalchemy-91ad6902c524f7d113dfd568288c0a5240ba9499.tar.gz
- Removed errant many-to-many load in unitofwork
which triggered unnecessarily on expired/unloaded collections. This load now takes place only if passive_updates is False and the parent primary key has changed, or if passive_deletes is False and a delete of the parent has occurred. [ticket:1845]
Diffstat (limited to 'lib/sqlalchemy/orm/dependency.py')
-rw-r--r--lib/sqlalchemy/orm/dependency.py68
1 files changed, 38 insertions, 30 deletions
diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py
index bd4473ef7..baa7af645 100644
--- a/lib/sqlalchemy/orm/dependency.py
+++ b/lib/sqlalchemy/orm/dependency.py
@@ -871,6 +871,9 @@ class ManyToManyDP(DependencyProcessor):
def presort_deletes(self, uowcommit, states):
if not self.passive_deletes:
+ # if no passive deletes, load history on
+ # the collection, so that prop_has_changes()
+ # returns True
for state in states:
history = uowcommit.get_attribute_history(
state,
@@ -878,16 +881,22 @@ class ManyToManyDP(DependencyProcessor):
passive=self.passive_deletes)
def presort_saves(self, uowcommit, states):
- for state in states:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- False)
+ if not self.passive_updates:
+ # if no passive updates, load history on
+ # each collection where parent has changed PK,
+ # so that prop_has_changes() returns True
+ for state in states:
+ if self._pks_changed(uowcommit, state):
+ history = uowcommit.get_attribute_history(
+ state,
+ self.key,
+ False)
-
if not self.cascade.delete_orphan:
return
-
+
+ # check for child items removed from the collection
+ # if delete_orphan check is turned on.
for state in states:
history = uowcommit.get_attribute_history(
state,
@@ -911,6 +920,8 @@ class ManyToManyDP(DependencyProcessor):
processed = self._get_reversed_processed_set(uowcommit)
tmp = set()
for state in states:
+ # this history should be cached already, as
+ # we loaded it in preprocess_deletes
history = uowcommit.get_attribute_history(
state,
self.key,
@@ -947,7 +958,10 @@ class ManyToManyDP(DependencyProcessor):
tmp = set()
for state in states:
- history = uowcommit.get_attribute_history(state, self.key)
+ need_cascade_pks = not self.passive_updates and \
+ self._pks_changed(uowcommit, state)
+ history = uowcommit.get_attribute_history(state, self.key,
+ passive=not need_cascade_pks)
if history:
for child in history.added:
if child is None or \
@@ -976,28 +990,22 @@ class ManyToManyDP(DependencyProcessor):
tmp.update((c, state)
for c in history.added + history.deleted)
- if not self.passive_updates and \
- self._pks_changed(uowcommit, state):
- if not history:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- passive=False)
-
- for child in history.unchanged:
- associationrow = {}
- sync.update(state,
- self.parent,
- associationrow,
- "old_",
- self.prop.synchronize_pairs)
- sync.update(child,
- self.mapper,
- associationrow,
- "old_",
- self.prop.secondary_synchronize_pairs)
-
- secondary_update.append(associationrow)
+ if need_cascade_pks:
+
+ for child in history.unchanged:
+ associationrow = {}
+ sync.update(state,
+ self.parent,
+ associationrow,
+ "old_",
+ self.prop.synchronize_pairs)
+ sync.update(child,
+ self.mapper,
+ associationrow,
+ "old_",
+ self.prop.secondary_synchronize_pairs)
+
+ secondary_update.append(associationrow)
if processed is not None:
processed.update(tmp)