From 67caec4e17987e0f62aa9bacacdec030e03d9f88 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 3 Apr 2010 17:03:12 -0400 Subject: [PATCH] - basic inheritance behavior - we do need dependencies between an object and its dep when the other object has no save or delete pending. the other object like before isn't needed, but right now we make the dependency just 'None', and it gets thrown away. --- lib/sqlalchemy/orm/dependency.py | 29 ++++++++++++++++------------- lib/sqlalchemy/orm/mapper.py | 3 ++- lib/sqlalchemy/orm/unitofwork.py | 12 +++++++++--- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py index df9213d3e6..0c3c532d9f 100644 --- a/lib/sqlalchemy/orm/dependency.py +++ b/lib/sqlalchemy/orm/dependency.py @@ -64,11 +64,11 @@ class DependencyProcessor(object): after_save = unitofwork.ProcessAll(uow, self, False, True) before_delete = unitofwork.ProcessAll(uow, self, True, True) - parent_saves = unitofwork.SaveUpdateAll(uow, self.parent) - child_saves = unitofwork.SaveUpdateAll(uow, self.mapper) + parent_saves = unitofwork.SaveUpdateAll(uow, self.parent.base_mapper) + child_saves = unitofwork.SaveUpdateAll(uow, self.mapper.base_mapper) - parent_deletes = unitofwork.DeleteAll(uow, self.parent) - child_deletes = unitofwork.DeleteAll(uow, self.mapper) + parent_deletes = unitofwork.DeleteAll(uow, self.parent.base_mapper) + child_deletes = unitofwork.DeleteAll(uow, self.mapper.base_mapper) self.per_property_dependencies(uow, parent_saves, @@ -85,8 +85,8 @@ class DependencyProcessor(object): before_delete.disabled = True # check if the "child" side is part of the cycle - child_saves = unitofwork.SaveUpdateAll(uow, self.mapper) - child_deletes = unitofwork.DeleteAll(uow, self.mapper) + 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: assert child_deletes not in uow.cycles # its not, so we will link per-state @@ -101,19 +101,22 @@ class DependencyProcessor(object): return child_actions = [] for child_state in sum_: - if child_state is None or child_state not in uow.states: + if child_state is None: continue - (deleted, listonly) = uow.states[child_state] - if deleted: - child_action = unitofwork.DeleteState(uow, child_state) + if child_state not in uow.states: + child_action = None else: - child_action = unitofwork.SaveUpdateState(uow, child_state) + (deleted, listonly) = uow.states[child_state] + if deleted: + child_action = unitofwork.DeleteState(uow, child_state) + else: + child_action = unitofwork.SaveUpdateState(uow, child_state) child_actions.append(child_action) # check if the "parent" side is part of the cycle, # if so break up parent_saves if not isdelete: - parent_saves = unitofwork.SaveUpdateAll(uow, self.parent) + parent_saves = unitofwork.SaveUpdateAll(uow, self.parent.base_mapper) if parent_saves in uow.cycles: parent_saves = unitofwork.SaveUpdateState(uow, state) @@ -122,7 +125,7 @@ class DependencyProcessor(object): parent_deletes = before_delete = None else: - parent_deletes = unitofwork.DeleteAll(uow, self.parent) + parent_deletes = unitofwork.DeleteAll(uow, self.parent.base_mapper) if parent_deletes in uow.cycles: parent_deletes = unitofwork.DeleteState(uow, state) before_delete = unitofwork.ProcessState(uow, self, True, state) diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 9a18bd4cf6..22b5e5177a 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -1269,7 +1269,8 @@ class Mapper(object): action = unitofwork.SaveUpdateState(uow, state) yield action - for prop in self._props.values(): + mapper = state.manager.mapper + for prop in mapper._props.values(): for rec in prop.per_state_flush_actions(uow, state, isdelete): yield rec diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 3118e0b9f9..76cdde6358 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -170,7 +170,9 @@ class UOWTransaction(object): break # see if the graph of mapper dependencies has cycles. - self.cycles = cycles = topological.find_cycles(self.dependencies, self.postsort_actions.values()) + self.cycles = cycles = topological.find_cycles( + self.dependencies, + self.postsort_actions.values()) if cycles: # if yes, break the per-mapper actions into @@ -184,7 +186,9 @@ class UOWTransaction(object): # the per-state actions for those per-mapper actions # that were broken up. for edge in list(self.dependencies): - if cycles.issuperset(edge): + if None in edge: + self.dependencies.remove(edge) + elif cycles.issuperset(edge): self.dependencies.remove(edge) elif edge[0] in cycles: self.dependencies.remove(edge) @@ -317,7 +321,8 @@ class ProcessAll(PropertyRecMixin, PostSortRec): class SaveUpdateAll(PostSortRec): def __init__(self, uow, mapper): self.mapper = mapper - + assert mapper is mapper.base_mapper + def execute(self, uow): self.mapper._save_obj( uow.states_for_mapper_hierarchy(self.mapper, False, False), @@ -332,6 +337,7 @@ class SaveUpdateAll(PostSortRec): class DeleteAll(PostSortRec): def __init__(self, uow, mapper): self.mapper = mapper + assert mapper is mapper.base_mapper def execute(self, uow): self.mapper._delete_obj( -- 2.47.3