diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-07-21 21:47:03 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-07-21 21:47:03 +0000 |
| commit | b9b62b2369e00be2f344dd96aec94e88c9210fb0 (patch) | |
| tree | 0e4847721ea0aef81917c57401aa020f8f967a8b /lib | |
| parent | f300bb43dedd54a81f5bd72fd9afad1c2bb39ede (diff) | |
| download | sqlalchemy-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.py | 43 |
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, |
