summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/descriptor_props.py9
-rw-r--r--lib/sqlalchemy/orm/dynamic.py3
-rw-r--r--lib/sqlalchemy/orm/interfaces.py34
-rw-r--r--lib/sqlalchemy/orm/mapper.py12
-rw-r--r--lib/sqlalchemy/orm/query.py21
-rw-r--r--lib/sqlalchemy/orm/strategies.py76
6 files changed, 80 insertions, 75 deletions
diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py
index 18c1081f3..3344ed888 100644
--- a/lib/sqlalchemy/orm/descriptor_props.py
+++ b/lib/sqlalchemy/orm/descriptor_props.py
@@ -85,15 +85,6 @@ class DescriptorProperty(MapperProperty):
descriptor.impl = _ProxyImpl(self.key)
mapper.class_manager.instrument_attribute(self.key, descriptor)
- def setup(self, context, entity, path, adapter, **kwargs):
- pass
-
- def create_row_processor(self, selectcontext, path, mapper, row, adapter):
- return None, None, None
-
- def merge(self, session, source_state, source_dict,
- dest_state, dest_dict, load, _recursive):
- pass
class CompositeProperty(DescriptorProperty):
diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py
index 2094b1cb0..66f7bf739 100644
--- a/lib/sqlalchemy/orm/dynamic.py
+++ b/lib/sqlalchemy/orm/dynamic.py
@@ -35,9 +35,6 @@ class DynaLoader(strategies.AbstractRelationshipLoader):
query_class=self.parent_property.query_class
)
- def create_row_processor(self, selectcontext, path, mapper, row, adapter):
- return None, None, None
-
log.class_logger(DynaLoader)
class DynamicAttributeImpl(attributes.AttributeImpl):
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index d50aea83a..47f63a7d6 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -71,7 +71,7 @@ class MapperProperty(object):
"""
- def setup(self, context, entity, path, adapter, **kwargs):
+ def setup(self, context, entity, path, reduced_path, adapter, **kwargs):
"""Called by Query for the purposes of constructing a SQL statement.
Each MapperProperty associated with the target mapper processes the
@@ -81,12 +81,12 @@ class MapperProperty(object):
pass
- def create_row_processor(self, selectcontext, path, mapper, row, adapter):
+ def create_row_processor(self, selectcontext, path, reduced_path,
+ mapper, row, adapter):
"""Return a 3-tuple consisting of three row processing functions.
"""
-
- raise NotImplementedError()
+ return None, None, None
def cascade_iterator(self, type_, state, visited_instances=None,
halt_on=None):
@@ -166,7 +166,7 @@ class MapperProperty(object):
"""Merge the attribute represented by this ``MapperProperty``
from source to destination object"""
- raise NotImplementedError()
+ pass
def compare(self, operator, value):
"""Return a compare operation for the columns represented by
@@ -295,8 +295,8 @@ class StrategizedProperty(MapperProperty):
"""
- def _get_context_strategy(self, context, path):
- key = ('loaderstrategy', _reduce_path(path))
+ def _get_context_strategy(self, context, reduced_path):
+ key = ('loaderstrategy', reduced_path)
if key in context.attributes:
cls = context.attributes[key]
try:
@@ -317,13 +317,15 @@ class StrategizedProperty(MapperProperty):
strategy.init()
return strategy
- def setup(self, context, entity, path, adapter, **kwargs):
- self._get_context_strategy(context, path + (self.key,)).\
- setup_query(context, entity, path, adapter, **kwargs)
+ def setup(self, context, entity, path, reduced_path, adapter, **kwargs):
+ self._get_context_strategy(context, reduced_path + (self.key,)).\
+ setup_query(context, entity, path,
+ reduced_path, adapter, **kwargs)
- def create_row_processor(self, context, path, mapper, row, adapter):
- return self._get_context_strategy(context, path + (self.key,)).\
- create_row_processor(context, path, mapper, row, adapter)
+ def create_row_processor(self, context, path, reduced_path, mapper, row, adapter):
+ return self._get_context_strategy(context, reduced_path + (self.key,)).\
+ create_row_processor(context, path,
+ reduced_path, mapper, row, adapter)
def do_init(self):
self._strategies = {}
@@ -587,10 +589,10 @@ class LoaderStrategy(object):
def init_class_attribute(self, mapper):
pass
- def setup_query(self, context, entity, path, adapter, **kwargs):
+ def setup_query(self, context, entity, path, reduced_path, adapter, **kwargs):
pass
- def create_row_processor(self, selectcontext, path, mapper,
+ def create_row_processor(self, selectcontext, path, reduced_path, mapper,
row, adapter):
"""Return row processing functions which fulfill the contract
specified by MapperProperty.create_row_processor.
@@ -598,7 +600,7 @@ class LoaderStrategy(object):
StrategizedProperty delegates its create_row_processor method
directly to this method. """
- raise NotImplementedError()
+ return None, None, None
def __str__(self):
return str(self.parent_property)
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index fa227a1f1..8c1db3f1a 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -2068,7 +2068,7 @@ class Mapper(object):
for state, state_dict, mapper, has_identity, connection in tups:
mapper.dispatch.on_after_delete(mapper, connection, state)
- def _instance_processor(self, context, path, adapter,
+ def _instance_processor(self, context, path, reduced_path, adapter,
polymorphic_from=None,
only_load_props=None, refresh_state=None,
polymorphic_discriminator=None):
@@ -2087,7 +2087,7 @@ class Mapper(object):
polymorphic_on = self.polymorphic_on
polymorphic_instances = util.PopulateDict(
self._configure_subclass_mapper(
- context, path, adapter)
+ context, path, reduced_path, adapter)
)
version_id_col = self.version_id_col
@@ -2115,7 +2115,7 @@ class Mapper(object):
state.load_path = load_path
if not new_populators:
- self._populators(context, path, row, adapter,
+ self._populators(context, path, reduced_path, row, adapter,
new_populators,
existing_populators
)
@@ -2307,7 +2307,7 @@ class Mapper(object):
return instance
return _instance
- def _populators(self, context, path, row, adapter,
+ def _populators(self, context, path, reduced_path, row, adapter,
new_populators, existing_populators):
"""Produce a collection of attribute level row processor callables."""
@@ -2315,6 +2315,7 @@ class Mapper(object):
for prop in self._props.itervalues():
newpop, existingpop, delayedpop = prop.create_row_processor(
context, path,
+ reduced_path,
self, row, adapter)
if newpop:
new_populators.append((prop.key, newpop))
@@ -2325,7 +2326,7 @@ class Mapper(object):
if delayed_populators:
new_populators.extend(delayed_populators)
- def _configure_subclass_mapper(self, context, path, adapter):
+ def _configure_subclass_mapper(self, context, path, reduced_path, adapter):
"""Produce a mapper level row processor callable factory for mappers
inheriting this one."""
@@ -2349,6 +2350,7 @@ class Mapper(object):
#assert mapper.isa(_class_to_mapper(path[-1]))
return mapper._instance_processor(context, path[0:-1] + (mapper,),
+ reduced_path[0:-1] + (mapper.base_mapper,),
adapter,
polymorphic_from=self)
return configure_subclass_mapper
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 9acb3485f..9c0381f75 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -2567,13 +2567,18 @@ class _MapperEntity(_QueryEntity):
self._polymorphic_discriminator = None
self.is_aliased_class = is_aliased_class
if is_aliased_class:
- self.path_entity = self.entity = self.entity_zero = entity
- self._label_name = self.entity._sa_label_name
+ self.path_entity = self.entity_zero = entity
+ self._path = (entity,)
+ self._label_name = self.entity_zero._sa_label_name
+ self._reduced_path = (self.path_entity, )
else:
self.path_entity = mapper
- self.entity = self.entity_zero = mapper
+ self._path = (mapper,)
+ self._reduced_path = (mapper.base_mapper, )
+ self.entity_zero = mapper
self._label_name = self.mapper.class_.__name__
+
def set_with_polymorphic(self, query, cls_or_mappers,
selectable, discriminator):
if cls_or_mappers is None:
@@ -2642,7 +2647,8 @@ class _MapperEntity(_QueryEntity):
if self.primary_entity:
_instance = self.mapper._instance_processor(
context,
- (self.path_entity,),
+ self._path,
+ self._reduced_path,
adapter,
only_load_props=query._only_load_props,
refresh_state=context.refresh_state,
@@ -2652,7 +2658,8 @@ class _MapperEntity(_QueryEntity):
else:
_instance = self.mapper._instance_processor(
context,
- (self.path_entity,),
+ self._path,
+ self._reduced_path,
adapter,
polymorphic_discriminator=
self._polymorphic_discriminator)
@@ -2680,6 +2687,7 @@ class _MapperEntity(_QueryEntity):
self._with_polymorphic)
else:
poly_properties = self.mapper._polymorphic_properties
+
for value in poly_properties:
if query._only_load_props and \
value.key not in query._only_load_props:
@@ -2687,7 +2695,8 @@ class _MapperEntity(_QueryEntity):
value.setup(
context,
self,
- (self.path_entity,),
+ self._path,
+ self._reduced_path,
adapter,
only_load_props=query._only_load_props,
column_collection=context.primary_columns
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index ec2c3c2bc..92fd74f78 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -99,14 +99,14 @@ class UninstrumentedColumnLoader(LoaderStrategy):
def init(self):
self.columns = self.parent_property.columns
- def setup_query(self, context, entity, path, adapter,
+ def setup_query(self, context, entity, path, reduced_path, adapter,
column_collection=None, **kwargs):
for c in self.columns:
if adapter:
c = adapter.columns[c]
column_collection.append(c)
- def create_row_processor(self, selectcontext, path, mapper, row, adapter):
+ def create_row_processor(self, selectcontext, path, reduced_path, mapper, row, adapter):
return None, None, None
class ColumnLoader(LoaderStrategy):
@@ -116,7 +116,7 @@ class ColumnLoader(LoaderStrategy):
self.columns = self.parent_property.columns
self.is_composite = hasattr(self.parent_property, 'composite_class')
- def setup_query(self, context, entity, path, adapter,
+ def setup_query(self, context, entity, path, reduced_path, adapter,
column_collection=None, **kwargs):
for c in self.columns:
if adapter:
@@ -137,7 +137,7 @@ class ColumnLoader(LoaderStrategy):
active_history = active_history
)
- def create_row_processor(self, selectcontext, path, mapper, row, adapter):
+ def create_row_processor(self, selectcontext, path, reduced_path, mapper, row, adapter):
key = self.key
# look through list of columns represented here
# to see which, if any, is present in the row.
@@ -158,7 +158,7 @@ log.class_logger(ColumnLoader)
class DeferredColumnLoader(LoaderStrategy):
"""Strategize the loading of a deferred column-based MapperProperty."""
- def create_row_processor(self, selectcontext, path, mapper, row, adapter):
+ def create_row_processor(self, selectcontext, path, reduced_path, mapper, row, adapter):
col = self.columns[0]
if adapter:
col = adapter.columns[col]
@@ -167,7 +167,7 @@ class DeferredColumnLoader(LoaderStrategy):
if col in row:
return self.parent_property._get_strategy(ColumnLoader).\
create_row_processor(
- selectcontext, path, mapper, row, adapter)
+ selectcontext, path, reduced_path, mapper, row, adapter)
elif not self.is_class_level:
def new_execute(state, dict_, row):
@@ -198,7 +198,7 @@ class DeferredColumnLoader(LoaderStrategy):
expire_missing=False
)
- def setup_query(self, context, entity, path, adapter,
+ def setup_query(self, context, entity, path, reduced_path, adapter,
only_load_props=None, **kwargs):
if (
self.group is not None and
@@ -206,7 +206,7 @@ class DeferredColumnLoader(LoaderStrategy):
) or (only_load_props and self.key in only_load_props):
self.parent_property._get_strategy(ColumnLoader).\
setup_query(context, entity,
- path, adapter, **kwargs)
+ path, reduced_path, adapter, **kwargs)
def _load_for_state(self, state, passive):
if not state.key:
@@ -305,7 +305,7 @@ class NoLoader(AbstractRelationshipLoader):
typecallable = self.parent_property.collection_class,
)
- def create_row_processor(self, selectcontext, path, mapper, row, adapter):
+ def create_row_processor(self, selectcontext, path, reduced_path, mapper, row, adapter):
def new_execute(state, dict_, row):
state.initialize(self.key)
return new_execute, None, None
@@ -548,7 +548,8 @@ class LazyLoader(AbstractRelationshipLoader):
else:
return None
- def create_row_processor(self, selectcontext, path, mapper, row, adapter):
+ def create_row_processor(self, selectcontext, path, reduced_path,
+ mapper, row, adapter):
key = self.key
if not self.is_class_level:
def new_execute(state, dict_, row):
@@ -644,11 +645,11 @@ class ImmediateLoader(AbstractRelationshipLoader):
init_class_attribute(mapper)
def setup_query(self, context, entity,
- path, adapter, column_collection=None,
+ path, reduced_path, adapter, column_collection=None,
parentmapper=None, **kwargs):
pass
- def create_row_processor(self, context, path, mapper, row, adapter):
+ def create_row_processor(self, context, path, reduced_path, mapper, row, adapter):
def execute(state, dict_, row):
state.get_impl(self.key).get(state, dict_)
@@ -665,22 +666,21 @@ class SubqueryLoader(AbstractRelationshipLoader):
init_class_attribute(mapper)
def setup_query(self, context, entity,
- path, adapter, column_collection=None,
+ path, reduced_path, adapter, column_collection=None,
parentmapper=None, **kwargs):
if not context.query._enable_eagerloads:
return
path = path + (self.key, )
-
+ reduced_path = reduced_path + (self.key, )
+
# build up a path indicating the path from the leftmost
# entity to the thing we're subquery loading.
subq_path = context.attributes.get(('subquery_path', None), ())
subq_path = subq_path + path
- reduced_path = interfaces._reduce_path(path)
-
# join-depth / recursion check
if ("loaderstrategy", reduced_path) not in context.attributes:
if self.join_depth:
@@ -820,18 +820,17 @@ class SubqueryLoader(AbstractRelationshipLoader):
secondary_synchronize_pairs
]
- def create_row_processor(self, context, path, mapper, row, adapter):
+ def create_row_processor(self, context, path, reduced_path,
+ mapper, row, adapter):
if not self.parent.class_manager[self.key].impl.supports_population:
raise sa_exc.InvalidRequestError(
"'%s' does not support object "
"population - eager loading cannot be applied." %
self)
- path = path + (self.key,)
-
- path = interfaces._reduce_path(path)
+ reduced_path = reduced_path + (self.key,)
- if ('subquery', path) not in context.attributes:
+ if ('subquery', reduced_path) not in context.attributes:
return None, None, None
local_cols, remote_cols = self._local_remote_columns(self.parent_property)
@@ -840,7 +839,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
self.mapper._columntoproperty[c].key
for c in remote_cols]
- q = context.attributes[('subquery', path)]
+ q = context.attributes[('subquery', reduced_path)]
collections = dict(
(k, [v[0] for v in v])
@@ -892,7 +891,7 @@ class EagerLoader(AbstractRelationshipLoader):
self.parent_property.\
_get_strategy(LazyLoader).init_class_attribute(mapper)
- def setup_query(self, context, entity, path, adapter, \
+ def setup_query(self, context, entity, path, reduced_path, adapter, \
column_collection=None, parentmapper=None,
allow_innerjoin=True,
**kwargs):
@@ -903,8 +902,7 @@ class EagerLoader(AbstractRelationshipLoader):
return
path = path + (self.key,)
-
- reduced_path = interfaces._reduce_path(path)
+ reduced_path = reduced_path + (self.key,)
# check for user-defined eager alias
if ("user_defined_eager_row_processor", reduced_path) in\
@@ -963,12 +961,16 @@ class EagerLoader(AbstractRelationshipLoader):
context.attributes[
("eager_row_processor", reduced_path)
] = clauses
-
+
+ path += (self.mapper,)
+ reduced_path += (self.mapper.base_mapper,)
+
for value in self.mapper._polymorphic_properties:
value.setup(
context,
entity,
- path + (self.mapper,),
+ path,
+ reduced_path,
clauses,
parentmapper=self.mapper,
column_collection=add_to_collection,
@@ -1069,8 +1071,7 @@ class EagerLoader(AbstractRelationshipLoader):
)
- def _create_eager_adapter(self, context, row, adapter, path):
- reduced_path = interfaces._reduce_path(path)
+ def _create_eager_adapter(self, context, row, adapter, path, reduced_path):
if ("user_defined_eager_row_processor", reduced_path) in \
context.attributes:
decorator = context.attributes[
@@ -1097,27 +1098,29 @@ class EagerLoader(AbstractRelationshipLoader):
# processor, will cause a degrade to lazy
return False
- def create_row_processor(self, context, path, mapper, row, adapter):
+ def create_row_processor(self, context, path, reduced_path, mapper, row, adapter):
if not self.parent.class_manager[self.key].impl.supports_population:
raise sa_exc.InvalidRequestError(
"'%s' does not support object "
"population - eager loading cannot be applied." %
self)
- path = path + (self.key,)
-
+ our_path = path + (self.key,)
+ our_reduced_path = reduced_path + (self.key,)
eager_adapter = self._create_eager_adapter(
context,
row,
- adapter, path)
+ adapter, our_path,
+ our_reduced_path)
if eager_adapter is not False:
key = self.key
_instance = self.mapper._instance_processor(
- context,
- path + (self.mapper,),
- eager_adapter)
+ context,
+ our_path + (self.mapper,),
+ our_reduced_path + (self.mapper.base_mapper,),
+ eager_adapter)
if not self.uselist:
def new_execute(state, dict_, row):
@@ -1167,6 +1170,7 @@ class EagerLoader(AbstractRelationshipLoader):
_get_strategy(LazyLoader).\
create_row_processor(
context, path,
+ reduced_path,
mapper, row, adapter)
log.class_logger(EagerLoader)