diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-10-01 14:23:01 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-10-01 14:23:01 -0400 |
| commit | 755aca7f5f3f33339dce4f4b6b92b8b7a9c3d180 (patch) | |
| tree | ad6e161c8c09162d7ef50f1f27bb592846f3d4b9 /lib/sqlalchemy | |
| parent | 2a2257b1e7d4abb8a7657e10542e0fa45c80a8ca (diff) | |
| download | sqlalchemy-755aca7f5f3f33339dce4f4b6b92b8b7a9c3d180.tar.gz | |
- reworked the internals of mapper.cascade_iterator() to
cut down method calls by about 9% in some circumstances.
[ticket:1932]
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 14 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 35 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/properties.py | 3 |
3 files changed, 35 insertions, 17 deletions
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 0a65c8a44..fa27859ec 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -76,7 +76,7 @@ class MapperExtension(object): mapper activity will not be performed. """ - + def instrument_class(self, mapper, class_): """Receive a class when the mapper is first constructed, and has applied instrumentation to the mapped class. @@ -418,6 +418,13 @@ class MapperProperty(object): attribute access, loading behavior, and dependency calculations. """ + cascade = () + """The set of 'cascade' attribute names. + + This collection is checked before the 'cascade_iterator' method is called. + + """ + def setup(self, context, entity, path, adapter, **kwargs): """Called by Query for the purposes of constructing a SQL statement. @@ -469,6 +476,11 @@ class MapperProperty(object): halt_on=None): """Iterate through instances related to the given instance for a particular 'cascade', starting with this MapperProperty. + + Return an iterator3-tuples (instance, mapper, state). + + Note that the 'cascade' collection on this MapperProperty is + checked first for the given type before cascade_iterator is called. See PropertyLoader for the related instance implementation. """ diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 49f5d2190..d27b99601 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -1401,25 +1401,30 @@ class Mapper(object): """ visited_instances = util.IdentitySet() - visitables = [(self._props.itervalues(), 'property', state)] + prp, mpp = object(), object() + + visitables = [(deque(self._props.values()), prp, state)] while visitables: iterator, item_type, parent_state = visitables[-1] - try: - if item_type == 'property': - prop = iterator.next() - visitables.append( - (prop.cascade_iterator(type_, parent_state, - visited_instances, halt_on), 'mapper', None) - ) - elif item_type == 'mapper': - instance, instance_mapper, corresponding_state = \ - iterator.next() - yield (instance, instance_mapper) - visitables.append((instance_mapper._props.itervalues(), - 'property', corresponding_state)) - except StopIteration: + if not iterator: visitables.pop() + continue + + if item_type is prp: + prop = iterator.popleft() + if type_ not in prop.cascade: + continue + queue = deque(prop.cascade_iterator(type_, parent_state, + visited_instances, halt_on)) + if queue: + visitables.append((queue,mpp, None)) + elif item_type is mpp: + instance, instance_mapper, corresponding_state = \ + iterator.popleft() + yield (instance, instance_mapper) + visitables.append((deque(instance_mapper._props.values()), + prp, corresponding_state)) @_memoized_compiled_property def _compiled_cache(self): diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index a5e6930b2..4efd2acc9 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -868,7 +868,8 @@ class RelationshipProperty(StrategizedProperty): # cascade using the mapper local to this # object, so that its individual properties are located instance_mapper = instance_state.manager.mapper - yield (c, instance_mapper, instance_state) + yield c, instance_mapper, instance_state + def _add_reverse_property(self, key): other = self.mapper.get_property(key, _compile_mappers=False) |
