diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-07-07 12:01:02 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-07-07 12:01:02 -0400 |
commit | 91ad6902c524f7d113dfd568288c0a5240ba9499 (patch) | |
tree | 06c915ef8ef96cf3167a44c7424e73535a834373 /lib/sqlalchemy/orm/dependency.py | |
parent | 406cedbeefb992247750ae25eb380ea40afb4a2c (diff) | |
download | sqlalchemy-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.py | 68 |
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) |