diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-04-03 19:41:56 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-04-03 19:41:56 -0400 |
| commit | 3d3095497b872696e8860763f54217f425c7d35b (patch) | |
| tree | 72aa4f6b477affde2139bb6616845bc6f04d6364 /lib | |
| parent | 85156a0fbe43f8691e19c077c92b0d433f9e654b (diff) | |
| download | sqlalchemy-3d3095497b872696e8860763f54217f425c7d35b.tar.gz | |
row switch works for post-cycle sorts too...just needed more data in the deps. the pattern here
is more data needed for each tweak.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/orm/dependency.py | 14 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 8 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/unitofwork.py | 27 |
3 files changed, 26 insertions, 23 deletions
diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py index 86cac2d87..398bdd91c 100644 --- a/lib/sqlalchemy/orm/dependency.py +++ b/lib/sqlalchemy/orm/dependency.py @@ -79,6 +79,8 @@ class DependencyProcessor(object): before_delete) def per_state_flush_actions(self, uow, state, isdelete): + # locate and disable the aggregate processors + # for this dependency after_save = unitofwork.ProcessAll(uow, self, False, True) before_delete = unitofwork.ProcessAll(uow, self, True, True) after_save.disabled = True @@ -88,14 +90,20 @@ class DependencyProcessor(object): child_saves = unitofwork.SaveUpdateAll(uow, self.mapper.base_mapper) child_deletes = unitofwork.DeleteAll(uow, self.mapper.base_mapper) if child_saves not in uow.cycles: + # based on the current dependencies we use, the saves/ + # deletes should always be in the 'cycles' collection + # together. if this changes, we will have to break up + # this method a bit more. assert child_deletes not in uow.cycles - # its not, so we will link per-state + + # child side is not part of the cycle, so we will link per-state # actions to the aggregate "saves", "deletes" actions child_actions = [ (child_saves, False), (child_deletes, True) ] else: - # it is. see if there's any objects. + # child side is part of the cycle. create dependencies for + # each related object. sum_ = uow.get_attribute_history(state, self.key, passive=True).sum() if not sum_: return @@ -114,7 +122,7 @@ class DependencyProcessor(object): child_actions.append(child_action) # check if the "parent" side is part of the cycle, - # if so break up parent_saves + # if so break up parent_saves or parent_deletes if not isdelete: parent_saves = unitofwork.SaveUpdateAll(uow, self.parent.base_mapper) if parent_saves in uow.cycles: diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 319b06158..ac35ce49b 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -1263,11 +1263,15 @@ class Mapper(object): prop.per_property_flush_actions(uow) def per_state_flush_actions(self, uow, state, isdelete): + # keep saves before deletes - + # this ensures 'row switch' operations work if isdelete: action = unitofwork.DeleteState(uow, state) + uow.dependencies.add((unitofwork.SaveUpdateAll(uow, self.base_mapper), action)) else: action = unitofwork.SaveUpdateState(uow, state) - + uow.dependencies.add((action, unitofwork.DeleteAll(uow, self.base_mapper))) + yield action mapper = state.manager.mapper for prop in mapper._props.values(): @@ -1354,7 +1358,7 @@ class Mapper(object): self._log_debug( "detected row switch for identity %s. will update %s, remove %s from " "transaction", instance_key, state_str(state), state_str(existing)) - + # remove the "delete" flag from the existing element uowtransaction.remove_state_actions(existing) row_switches[state] = existing diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index a4eb00f70..c8eca67eb 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -105,15 +105,7 @@ class UOWTransaction(object): def remove_state_actions(self, state): """remove pending actions for a state from the uowtransaction.""" - if state in self.states: - isdelete, listonly = self.states[state] - self.states[state] = (False, True) - if isdelete: - self.postsort_actions.pop((DeleteState, state), None) - else: - self.postsort_actions.pop((SaveUpdateState, state), None) - - + self.states[state] = (False, True) def get_attribute_history(self, state, key, passive=True): hashkey = ("history", state, key) @@ -223,11 +215,9 @@ class UOWTransaction(object): # execute actions sort = topological.sort(self.dependencies, self.postsort_actions.values()) - print "------------------------" -# import pdb -# pdb.set_trace() - print self.dependencies - print sort +# print "------------------------" +# print self.dependencies +# print sort for rec in sort: rec.execute(self) @@ -411,10 +401,11 @@ class DeleteState(PostSortRec): def execute(self, uow): mapper = self.state.manager.mapper.base_mapper - mapper._delete_obj( - [self.state], - uow - ) + if uow.states[self.state][0]: + mapper._delete_obj( + [self.state], + uow + ) def __repr__(self): return "%s(%s)" % ( |
