summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2009-07-21 21:47:03 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2009-07-21 21:47:03 +0000
commitb9b62b2369e00be2f344dd96aec94e88c9210fb0 (patch)
tree0e4847721ea0aef81917c57401aa020f8f967a8b /lib
parentf300bb43dedd54a81f5bd72fd9afad1c2bb39ede (diff)
downloadsqlalchemy-b9b62b2369e00be2f344dd96aec94e88c9210fb0.tar.gz
- relations() now have greater ability to be "overridden",
meaning a subclass that explicitly specifies a relation() overriding that of the parent class will be honored during a flush. This is currently to support many-to-many relations from concrete inheritance setups. Outside of that use case, YMMV. [ticket:1477]
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlalchemy/orm/unitofwork.py43
1 files changed, 36 insertions, 7 deletions
diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py
index da26c8d7b..ef5b9fc1a 100644
--- a/lib/sqlalchemy/orm/unitofwork.py
+++ b/lib/sqlalchemy/orm/unitofwork.py
@@ -430,6 +430,15 @@ class UOWTask(object):
yield rec
return collection
+ def _polymorphic_collection_filtered(fn):
+
+ def collection(self, mappers):
+ for task in self.polymorphic_tasks:
+ if task.mapper in mappers:
+ for rec in fn(task):
+ yield rec
+ return collection
+
@property
def elements(self):
return self._objects.values()
@@ -438,6 +447,10 @@ class UOWTask(object):
def polymorphic_elements(self):
return self.elements
+ @_polymorphic_collection_filtered
+ def filter_polymorphic_elements(self):
+ return self.elements
+
@property
def polymorphic_tosave_elements(self):
return [rec for rec in self.polymorphic_elements if not rec.isdelete]
@@ -642,7 +655,19 @@ class UOWDependencyProcessor(object):
def __init__(self, processor, targettask):
self.processor = processor
self.targettask = targettask
-
+ prop = processor.prop
+
+ # define a set of mappers which
+ # will filter the lists of entities
+ # this UOWDP processes. this allows
+ # MapperProperties to be overridden
+ # at least for concrete mappers.
+ self._mappers = set([
+ m
+ for m in self.processor.parent.polymorphic_iterator()
+ if m._props[prop.key] is prop
+ ]).union(self.processor.mapper.polymorphic_iterator())
+
def __repr__(self):
return "UOWDependencyProcessor(%s, %s)" % (str(self.processor), str(self.targettask))
@@ -673,12 +698,16 @@ class UOWDependencyProcessor(object):
return elem.state
ret = False
- elements = [getobj(elem) for elem in self.targettask.polymorphic_tosave_elements if self not in elem.preprocessed]
+ elements = [getobj(elem) for elem in
+ self.targettask.filter_polymorphic_elements(self._mappers)
+ if self not in elem.preprocessed and not elem.isdelete]
if elements:
ret = True
self.processor.preprocess_dependencies(self.targettask, elements, trans, delete=False)
- elements = [getobj(elem) for elem in self.targettask.polymorphic_todelete_elements if self not in elem.preprocessed]
+ elements = [getobj(elem) for elem in
+ self.targettask.filter_polymorphic_elements(self._mappers)
+ if self not in elem.preprocessed and elem.isdelete]
if elements:
ret = True
self.processor.preprocess_dependencies(self.targettask, elements, trans, delete=True)
@@ -687,10 +716,10 @@ class UOWDependencyProcessor(object):
def execute(self, trans, delete):
"""process all objects contained within this ``UOWDependencyProcessor``s target task."""
- if delete:
- elements = self.targettask.polymorphic_todelete_elements
- else:
- elements = self.targettask.polymorphic_tosave_elements
+
+ elements = [e for e in
+ self.targettask.filter_polymorphic_elements(self._mappers)
+ if e.isdelete==delete]
self.processor.process_dependencies(
self.targettask,