summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/dependency.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-06-18 11:36:35 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2010-06-18 11:36:35 -0400
commit46e0138405778379848e6c6f2ab424388724e555 (patch)
tree85ca8c4f1e12e0fcc7185a99a3726e370ad652ff /lib/sqlalchemy/orm/dependency.py
parent0276ec0cd874aafb06606c443e8cdeb692c232f9 (diff)
downloadsqlalchemy-46e0138405778379848e6c6f2ab424388724e555.tar.gz
this approach seems to allow many-to-one post updates to occur as a single action. for one-to-many, we
have it working the old way still. as usual the huge job is the tests. also I am not yet certain that post updates can always be a "full mapper" operation, i.e. are never involved in per-state dependencies, or even if the old approach supports that.
Diffstat (limited to 'lib/sqlalchemy/orm/dependency.py')
-rw-r--r--lib/sqlalchemy/orm/dependency.py81
1 files changed, 56 insertions, 25 deletions
diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py
index 7a8c4cf70..4d7a03894 100644
--- a/lib/sqlalchemy/orm/dependency.py
+++ b/lib/sqlalchemy/orm/dependency.py
@@ -83,7 +83,8 @@ class DependencyProcessor(object):
parent_deletes,
child_deletes,
after_save,
- before_delete)
+ before_delete
+ )
def per_state_flush_actions(self, uow, states, isdelete):
@@ -95,6 +96,11 @@ class DependencyProcessor(object):
"""
+ parent_base_mapper = self.parent.primary_base_mapper
+ child_base_mapper = self.mapper.primary_base_mapper
+ child_saves = unitofwork.SaveUpdateAll(uow, child_base_mapper)
+ child_deletes = unitofwork.DeleteAll(uow, child_base_mapper)
+
# locate and disable the aggregate processors
# for this dependency
@@ -107,11 +113,6 @@ class DependencyProcessor(object):
# check if the "child" side is part of the cycle
- parent_base_mapper = self.parent.primary_base_mapper
- child_base_mapper = self.mapper.primary_base_mapper
- child_saves = unitofwork.SaveUpdateAll(uow, child_base_mapper)
- child_deletes = unitofwork.DeleteAll(uow, child_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
@@ -196,7 +197,7 @@ class DependencyProcessor(object):
# establish dependencies between our possibly per-state
# parent action and our possibly per-state child action.
- for (child_action, childisdelete) in child_actions:
+ for child_action, childisdelete in child_actions:
self.per_state_dependencies(uow, parent_saves,
parent_deletes,
child_action,
@@ -265,14 +266,15 @@ class DependencyProcessor(object):
set
)
- def _post_update(self, state, uowcommit, related, processed):
+ def _post_update(self, state, uowcommit, related, processed, immediate):
if processed is not None and state in processed:
return
for x in related:
if x is not None:
uowcommit.issue_post_update(
state,
- [r for l, r in self.prop.synchronize_pairs]
+ [r for l, r in self.prop.synchronize_pairs],
+ immediate
)
if processed is not None:
processed.add(state)
@@ -292,13 +294,16 @@ class OneToManyDP(DependencyProcessor):
parent_deletes,
child_deletes,
after_save,
- before_delete):
+ before_delete,
+ ):
if self.post_update:
+
uow.dependencies.update([
(child_saves, after_save),
(parent_saves, after_save),
(before_delete, parent_deletes),
(before_delete, child_deletes),
+
])
else:
uow.dependencies.update([
@@ -321,29 +326,30 @@ class OneToManyDP(DependencyProcessor):
isdelete, childisdelete):
if self.post_update:
+
# TODO: this whole block is not covered
# by any tests
if not isdelete:
if childisdelete:
uow.dependencies.update([
(save_parent, after_save),
- (after_save, child_action)
+ (after_save, child_action),
])
else:
uow.dependencies.update([
(save_parent, after_save),
- (child_action, after_save)
+ (child_action, after_save),
])
else:
if childisdelete:
uow.dependencies.update([
(before_delete, delete_parent),
- (before_delete, child_action)
+ (before_delete, child_action),
])
else:
uow.dependencies.update([
- (before_delete, delete_parent),
- (child_action, before_delete)
+ (before_delete, delete_parent),
+ (child_action, before_delete),
])
elif not isdelete:
uow.dependencies.update([
@@ -449,7 +455,7 @@ class OneToManyDP(DependencyProcessor):
self._post_update(
child,
uowcommit,
- [state], processed)
+ [state], processed, True)
if self.post_update or not self.cascade.delete:
for child in set(history.unchanged).\
difference(children_added):
@@ -462,7 +468,7 @@ class OneToManyDP(DependencyProcessor):
self._post_update(
child,
uowcommit,
- [state], processed)
+ [state], processed, True)
# technically, we can even remove each child from the
# collection here too. but this would be a somewhat
# inconsistent behavior since it wouldn't happen if the old
@@ -482,7 +488,8 @@ class OneToManyDP(DependencyProcessor):
child,
uowcommit,
[state],
- processed
+ processed,
+ True
)
for child in history.deleted:
@@ -530,11 +537,19 @@ class ManyToOneDP(DependencyProcessor):
before_delete):
if self.post_update:
+ child_post_updates = unitofwork.PostUpdateThing(
+ uow, self.parent.primary_base_mapper, False)
+ child_pre_updates = unitofwork.PostUpdateThing(
+ uow, self.parent.primary_base_mapper, True)
+
uow.dependencies.update([
(child_saves, after_save),
(parent_saves, after_save),
(before_delete, parent_deletes),
(before_delete, child_deletes),
+ (after_save, child_post_updates),
+ (before_delete, child_pre_updates),
+ (child_pre_updates, child_deletes),
])
else:
uow.dependencies.update([
@@ -552,21 +567,36 @@ class ManyToOneDP(DependencyProcessor):
isdelete, childisdelete):
if self.post_update:
+
if not isdelete:
+ child_post_updates = unitofwork.PostUpdateThing(
+ uow, self.parent.primary_base_mapper, False)
if childisdelete:
uow.dependencies.update([
(save_parent, after_save),
- (after_save, child_action)
+ (after_save, child_action), # can remove
+
+ (after_save, child_post_updates),
+ (child_post_updates, child_action)
])
else:
uow.dependencies.update([
(save_parent, after_save),
- (child_action, after_save)
+ (child_action, after_save),
+
+ (after_save, child_post_updates)
])
else:
+ child_pre_updates = unitofwork.PostUpdateThing(
+ uow, self.parent.primary_base_mapper, True)
+
uow.dependencies.update([
- (before_delete, delete_parent),
- (before_delete, child_action)
+ (before_delete, delete_parent), # can remove
+ (before_delete, child_action), # can remove
+
+ (before_delete, child_pre_updates),
+ (child_pre_updates, delete_parent),
+ (child_pre_updates, child_action)
])
elif not isdelete:
@@ -647,7 +677,7 @@ class ManyToOneDP(DependencyProcessor):
self._post_update(
state,
uowcommit,
- history.sum(), processed)
+ history.sum(), processed, False)
def process_saves(self, uowcommit, states):
if self.post_update:
@@ -662,7 +692,7 @@ class ManyToOneDP(DependencyProcessor):
if self.post_update:
self._post_update(
state,
- uowcommit, history.sum(), processed)
+ uowcommit, history.sum(), processed, False)
def _synchronize(self, state, child, associationrow, clearkeys, uowcommit):
if state is None or (not self.post_update and uowcommit.is_deleted(state)):
@@ -789,7 +819,8 @@ class ManyToManyDP(DependencyProcessor):
parent_deletes,
child_deletes,
after_save,
- before_delete):
+ before_delete
+ ):
uow.dependencies.update([
(parent_saves, after_save),