summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-07-16 20:09:38 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-07-16 20:09:38 -0400
commite45a4150fdd7e7f58dbe343706782a59a10d703b (patch)
tree735e55828deca4583fe7bf7fd4c6f9a7b8ecc48f /lib/sqlalchemy
parent747250587491ad76e30177b232daec5928f5b36d (diff)
downloadsqlalchemy-e45a4150fdd7e7f58dbe343706782a59a10d703b.tar.gz
- totally remove _entity_info and _extended_entity_info, replacing all usage
with inspect()
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/interfaces.py6
-rw-r--r--lib/sqlalchemy/orm/mapper.py25
-rw-r--r--lib/sqlalchemy/orm/properties.py8
-rw-r--r--lib/sqlalchemy/orm/query.py48
-rw-r--r--lib/sqlalchemy/orm/strategies.py274
-rw-r--r--lib/sqlalchemy/orm/util.py57
6 files changed, 212 insertions, 206 deletions
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index 1e47e6616..5b18bc137 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -18,7 +18,7 @@ classes within should be considered mostly private.
from __future__ import absolute_import
from itertools import chain
-from .. import exc as sa_exc, util
+from .. import exc as sa_exc, util, inspect
from ..sql import operators
from collections import deque
#from . import _instrumentation_ext
@@ -575,13 +575,13 @@ class PropertyOption(MapperOption):
if getattr(token, '_of_type', None):
ac = token._of_type
- ext_info = orm_util._extended_entity_info(ac)
+ ext_info = inspect(ac)
path_element = mapper = ext_info.mapper
if not ext_info.is_aliased_class:
ac = orm_util.with_polymorphic(
ext_info.mapper.base_mapper,
ext_info.mapper, aliased=True)
- ext_info = orm_util._extended_entity_info(ac)
+ ext_info = inspect(ac)
path.set(query, "path_with_polymorphic", ext_info)
else:
path_element = mapper = getattr(prop, 'mapper', None)
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 01b4d3a0f..39591ef99 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -213,6 +213,15 @@ class Mapper(_InspectionAttr):
"""
return self
+ @property
+ def entity(self):
+ """Part of the inspection API.
+
+ Returns self.class_.
+
+ """
+ return self.class_
+
local_table = None
"""The :class:`.Selectable` which this :class:`.Mapper` manages.
@@ -1390,15 +1399,17 @@ class Mapper(_InspectionAttr):
"""
- selectable = _with_polymorphic_selectable
- """The :func:`.select` construct this :class:`.Mapper` selects from
- by default.
+ @property
+ def selectable(self):
+ """The :func:`.select` construct this :class:`.Mapper` selects from
+ by default.
- Normally, this is equivalent to :attr:`.mapped_table`, unless
- the ``with_polymorphic`` feature is in use, in which case the
- full "polymoprhic" selectable is returned.
+ Normally, this is equivalent to :attr:`.mapped_table`, unless
+ the ``with_polymorphic`` feature is in use, in which case the
+ full "polymoprhic" selectable is returned.
- """
+ """
+ return self._with_polymorphic_selectable
def _with_polymorphic_args(self, spec=None, selectable=False,
innerjoin=False):
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 6b1dd6462..044ba8e2c 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -11,7 +11,7 @@ mapped attributes.
"""
-from .. import sql, util, log, exc as sa_exc
+from .. import sql, util, log, exc as sa_exc, inspect
from ..sql import operators, expression
from . import (
attributes, mapper,
@@ -19,7 +19,7 @@ from . import (
dependency
)
from .util import CascadeOptions, \
- _orm_annotate, _orm_deannotate, _orm_full_deannotate, _entity_info
+ _orm_annotate, _orm_deannotate, _orm_full_deannotate
from .interfaces import MANYTOMANY, MANYTOONE, ONETOMANY,\
PropComparator, StrategizedProperty
@@ -409,7 +409,9 @@ class RelationshipProperty(StrategizedProperty):
def _criterion_exists(self, criterion=None, **kwargs):
if getattr(self, '_of_type', None):
- target_mapper, to_selectable, is_aliased_class = _entity_info(self._of_type)
+ info = inspect(self._of_type)
+ target_mapper, to_selectable, is_aliased_class = \
+ info.mapper, info.selectable, info.is_aliased_class
if self.property._is_self_referential and not is_aliased_class:
to_selectable = to_selectable.alias()
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index f981399db..44f9ba7e5 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -25,12 +25,11 @@ from . import (
exc as orm_exc, loading
)
from .util import (
- AliasedClass, ORMAdapter, _entity_descriptor, _entity_info,
- _extended_entity_info, PathRegistry,
+ AliasedClass, ORMAdapter, _entity_descriptor, PathRegistry,
_is_aliased_class, _is_mapped_class, _orm_columns, _orm_selectable,
join as orm_join,with_parent, aliased
)
-from .. import sql, util, log, exc as sa_exc
+from .. import sql, util, log, exc as sa_exc, inspect
from ..sql import (
util as sql_util,
expression, visitors
@@ -127,7 +126,7 @@ class Query(object):
for ent in entities:
for entity in ent.entities:
if entity not in d:
- ext_info = _extended_entity_info(entity)
+ ext_info = inspect(entity)
if not ext_info.is_aliased_class and \
ext_info.mapper.with_polymorphic:
if ext_info.mapper.mapped_table not in \
@@ -1077,7 +1076,7 @@ class Query(object):
:class:`.Table`, :class:`.Alias`, or ORM entity / mapped class
/etc.
"""
- mapper, selectable, is_aliased_class = _entity_info(selectable)
+ selectable = inspect(selectable).selectable
self._with_hints += ((selectable, text, dialect_name),)
@@ -1719,8 +1718,12 @@ class Query(object):
isinstance(onclause, interfaces.PropComparator):
left_entity = onclause.parententity
+ info = inspect(self._joinpoint_zero())
left_mapper, left_selectable, left_is_aliased = \
- _entity_info(self._joinpoint_zero())
+ getattr(info, 'mapper', None), \
+ info.selectable, \
+ getattr(info, 'is_aliased_class', None)
+
if left_mapper is left_entity:
left_entity = self._joinpoint_zero()
descriptor = _entity_descriptor(left_entity,
@@ -1810,10 +1813,15 @@ class Query(object):
def _prepare_right_side(self, right, onclause, outerjoin,
create_aliases, prop):
- right_mapper, right_selectable, right_is_aliased = _entity_info(right)
+ info = inspect(right)
+
+ right_mapper, right_selectable, right_is_aliased = \
+ getattr(info, 'mapper', None), \
+ info.selectable, \
+ getattr(info, 'is_aliased_class', False)
if right_mapper:
- self._join_entities += (right, )
+ self._join_entities += (info, )
if right_mapper and prop and \
not right_mapper.common_parent(prop.mapper):
@@ -1883,8 +1891,13 @@ class Query(object):
return right, right_is_aliased, onclause
- def _join_to_left(self, left, right, right_is_aliased, onclause, outerjoin):
- left_mapper, left_selectable, left_is_aliased = _entity_info(left)
+ def _join_to_left(self, left, right, right_is_aliased,
+ onclause, outerjoin):
+ info = inspect(left)
+ left_mapper, left_selectable, left_is_aliased = \
+ getattr(info, 'mapper', None),\
+ info.selectable,\
+ getattr(info, 'is_aliased_class', False)
# this is an overly broad assumption here, but there's a
# very wide variety of situations where we rely upon orm.join's
@@ -1990,11 +2003,12 @@ class Query(object):
"""
obj = []
for fo in from_obj:
- if _is_mapped_class(fo):
- mapper, selectable, is_aliased_class = _entity_info(fo)
+ info = inspect(fo)
+ if hasattr(info, 'mapper') and \
+ (info.is_mapper or info.is_aliased_class):
self._select_from_entity = fo
- obj.append(selectable)
- elif not isinstance(fo, expression.FromClause):
+ obj.append(info.selectable)
+ elif not info.is_selectable:
raise sa_exc.ArgumentError(
"select_from() accepts FromClause objects only.")
else:
@@ -2669,7 +2683,7 @@ class Query(object):
"""
for (ext_info, adapter) in self._mapper_adapter_map.values():
- if ext_info.entity in self._join_entities:
+ if ext_info in self._join_entities:
continue
single_crit = ext_info.mapper._single_table_criterion
if single_crit is not None:
@@ -2718,7 +2732,7 @@ class _MapperEntity(_QueryEntity):
self.is_aliased_class = ext_info.is_aliased_class
self._with_polymorphic = ext_info.with_polymorphic_mappers
self._polymorphic_discriminator = \
- ext_info.with_polymorphic_discriminator
+ ext_info.polymorphic_on
if ext_info.is_aliased_class:
self.entity_zero = ext_info.entity
self._label_name = self.entity_zero._sa_label_name
@@ -2760,7 +2774,7 @@ class _MapperEntity(_QueryEntity):
return self.entity_zero
def corresponds_to(self, entity):
- entity_info = _extended_entity_info(entity)
+ entity_info = inspect(entity)
if entity_info.is_aliased_class or self.is_aliased_class:
return entity is self.entity_zero \
or \
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 2bd60e76d..21214af9a 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -4,14 +4,14 @@
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-"""sqlalchemy.orm.interfaces.LoaderStrategy
+"""sqlalchemy.orm.interfaces.LoaderStrategy
implementations, and related MapperOptions."""
-from .. import exc as sa_exc
+from .. import exc as sa_exc, inspect
from .. import util, log, event
from ..sql import util as sql_util, visitors
from . import (
- attributes, interfaces, exc as orm_exc, loading,
+ attributes, interfaces, exc as orm_exc, loading,
unitofwork, util as orm_util
)
from .util import _none_set
@@ -23,13 +23,13 @@ from .session import _state_session
import itertools
def _register_attribute(strategy, mapper, useobject,
- compare_function=None,
+ compare_function=None,
typecallable=None,
uselist=False,
- callable_=None,
- proxy_property=None,
+ callable_=None,
+ proxy_property=None,
active_history=False,
- impl_class=None,
+ impl_class=None,
**kw
):
@@ -45,7 +45,7 @@ def _register_attribute(strategy, mapper, useobject,
if prop.key in prop.parent.validators:
fn, include_removes = prop.parent.validators[prop.key]
listen_hooks.append(
- lambda desc, prop: orm_util._validator_events(desc,
+ lambda desc, prop: orm_util._validator_events(desc,
prop.key, fn, include_removes)
)
@@ -57,8 +57,8 @@ def _register_attribute(strategy, mapper, useobject,
backref = kw.pop('backref', None)
if backref:
listen_hooks.append(
- lambda desc, prop: attributes.backref_listeners(desc,
- backref,
+ lambda desc, prop: attributes.backref_listeners(desc,
+ backref,
uselist)
)
@@ -66,17 +66,17 @@ def _register_attribute(strategy, mapper, useobject,
if prop is m._props.get(prop.key):
desc = attributes.register_attribute_impl(
- m.class_,
- prop.key,
+ m.class_,
+ prop.key,
parent_token=prop,
- uselist=uselist,
- compare_function=compare_function,
+ uselist=uselist,
+ compare_function=compare_function,
useobject=useobject,
- extension=attribute_ext,
- trackparent=useobject and (prop.single_parent
- or prop.direction is interfaces.ONETOMANY),
+ extension=attribute_ext,
+ trackparent=useobject and (prop.single_parent
+ or prop.direction is interfaces.ONETOMANY),
typecallable=typecallable,
- callable_=callable_,
+ callable_=callable_,
active_history=active_history,
impl_class=impl_class,
doc=prop.doc,
@@ -97,7 +97,7 @@ class UninstrumentedColumnLoader(LoaderStrategy):
super(UninstrumentedColumnLoader, self).__init__(parent)
self.columns = self.parent_property.columns
- def setup_query(self, context, entity, path, adapter,
+ def setup_query(self, context, entity, path, adapter,
column_collection=None, **kwargs):
for c in self.columns:
if adapter:
@@ -115,7 +115,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,
+ def setup_query(self, context, entity, path,
adapter, column_collection, **kwargs):
for c in self.columns:
if adapter:
@@ -134,7 +134,7 @@ class ColumnLoader(LoaderStrategy):
active_history = active_history
)
- def create_row_processor(self, context, path,
+ def create_row_processor(self, context, path,
mapper, row, adapter):
key = self.key
# look through list of columns represented here
@@ -195,10 +195,10 @@ class DeferredColumnLoader(LoaderStrategy):
expire_missing=False
)
- def setup_query(self, context, entity, path, adapter,
+ def setup_query(self, context, entity, path, adapter,
only_load_props=None, **kwargs):
if (
- self.group is not None and
+ self.group is not None and
context.attributes.get(('undefer', self.group), False)
) or (only_load_props and self.key in only_load_props):
self.parent_property._get_strategy(ColumnLoader).\
@@ -216,10 +216,10 @@ class DeferredColumnLoader(LoaderStrategy):
if self.group:
toload = [
- p.key for p in
- localparent.iterate_properties
- if isinstance(p, StrategizedProperty) and
- isinstance(p.strategy, DeferredColumnLoader) and
+ p.key for p in
+ localparent.iterate_properties
+ if isinstance(p, StrategizedProperty) and
+ isinstance(p.strategy, DeferredColumnLoader) and
p.group==self.group
]
else:
@@ -232,12 +232,12 @@ class DeferredColumnLoader(LoaderStrategy):
if session is None:
raise orm_exc.DetachedInstanceError(
"Parent instance %s is not bound to a Session; "
- "deferred load operation of attribute '%s' cannot proceed" %
+ "deferred load operation of attribute '%s' cannot proceed" %
(orm_util.state_str(state), self.key)
)
query = session.query(localparent)
- if loading.load_on_ident(query, state.key,
+ if loading.load_on_ident(query, state.key,
only_load_props=group, refresh_state=state) is None:
raise orm_exc.ObjectDeletedError(state)
@@ -294,14 +294,14 @@ class AbstractRelationshipLoader(LoaderStrategy):
class NoLoader(AbstractRelationshipLoader):
"""Provide loading behavior for a :class:`.RelationshipProperty`
with "lazy=None".
-
+
"""
def init_class_attribute(self, mapper):
self.is_class_level = True
_register_attribute(self, mapper,
- useobject=True,
+ useobject=True,
uselist=self.parent_property.uselist,
typecallable = self.parent_property.collection_class,
)
@@ -316,7 +316,7 @@ log.class_logger(NoLoader)
class LazyLoader(AbstractRelationshipLoader):
"""Provide loading behavior for a :class:`.RelationshipProperty`
with "lazy=True", that is loads when first accessed.
-
+
"""
def __init__(self, parent):
@@ -338,8 +338,8 @@ class LazyLoader(AbstractRelationshipLoader):
#from sqlalchemy.orm import query
self.use_get = not self.uselist and \
self.mapper._get_clause[0].compare(
- self._lazywhere,
- use_proxies=True,
+ self._lazywhere,
+ use_proxies=True,
equivalents=self.mapper._equivalent_columns
)
@@ -355,13 +355,13 @@ class LazyLoader(AbstractRelationshipLoader):
def init_class_attribute(self, mapper):
self.is_class_level = True
- # MANYTOONE currently only needs the
+ # MANYTOONE currently only needs the
# "old" value for delete-orphan
- # cascades. the required _SingleParentValidator
+ # cascades. the required _SingleParentValidator
# will enable active_history
- # in that case. otherwise we don't need the
+ # in that case. otherwise we don't need the
# "old" value during backref operations.
- _register_attribute(self,
+ _register_attribute(self,
mapper,
useobject=True,
callable_=self._load_for_state,
@@ -375,12 +375,12 @@ class LazyLoader(AbstractRelationshipLoader):
not self.use_get,
)
- def lazy_clause(self, state, reverse_direction=False,
- alias_secondary=False,
+ def lazy_clause(self, state, reverse_direction=False,
+ alias_secondary=False,
adapt_source=None):
if state is None:
return self._lazy_none_clause(
- reverse_direction,
+ reverse_direction,
adapt_source=adapt_source)
if not reverse_direction:
@@ -411,14 +411,14 @@ class LazyLoader(AbstractRelationshipLoader):
if bindparam._identifying_key in bind_to_col:
bindparam.callable = \
lambda: mapper._get_committed_state_attr_by_column(
- state, dict_,
+ state, dict_,
bind_to_col[bindparam._identifying_key])
else:
def visit_bindparam(bindparam):
if bindparam._identifying_key in bind_to_col:
bindparam.callable = \
lambda: mapper._get_state_attr_by_column(
- state, dict_,
+ state, dict_,
bind_to_col[bindparam._identifying_key])
@@ -477,11 +477,11 @@ class LazyLoader(AbstractRelationshipLoader):
if not session:
raise orm_exc.DetachedInstanceError(
"Parent instance %s is not bound to a Session; "
- "lazy load operation of attribute '%s' cannot proceed" %
+ "lazy load operation of attribute '%s' cannot proceed" %
(orm_util.state_str(state), self.key)
)
- # if we have a simple primary key load, check the
+ # if we have a simple primary key load, check the
# identity map without generating a Query at all
if self.use_get:
ident = self._get_ident_for_use_get(
@@ -550,7 +550,7 @@ class LazyLoader(AbstractRelationshipLoader):
q = q.order_by(*util.to_list(self.parent_property.order_by))
for rev in self.parent_property._reverse_property:
- # reverse props that are MANYTOONE are loading *this*
+ # reverse props that are MANYTOONE are loading *this*
# object from get(), so don't need to eager out to those.
if rev.direction is interfaces.MANYTOONE and \
rev._use_get and \
@@ -575,7 +575,7 @@ class LazyLoader(AbstractRelationshipLoader):
if l > 1:
util.warn(
"Multiple rows returned with "
- "uselist=False for lazily-loaded attribute '%s' "
+ "uselist=False for lazily-loaded attribute '%s' "
% self.parent_property)
return result[0]
@@ -583,30 +583,30 @@ class LazyLoader(AbstractRelationshipLoader):
return None
- def create_row_processor(self, context, path,
+ def create_row_processor(self, context, path,
mapper, row, adapter):
key = self.key
if not self.is_class_level:
def set_lazy_callable(state, dict_, row):
- # we are not the primary manager for this attribute
+ # we are not the primary manager for this attribute
# on this class - set up a
- # per-instance lazyloader, which will override the
+ # per-instance lazyloader, which will override the
# class-level behavior.
- # this currently only happens when using a
+ # this currently only happens when using a
# "lazyload" option on a "no load"
- # attribute - "eager" attributes always have a
+ # attribute - "eager" attributes always have a
# class-level lazyloader installed.
state.set_callable(dict_, key, LoadLazyAttribute(state, key))
return set_lazy_callable, None, None
else:
def reset_for_lazy_callable(state, dict_, row):
- # we are the primary manager for this attribute on
+ # we are the primary manager for this attribute on
# this class - reset its
- # per-instance attribute state, so that the class-level
+ # per-instance attribute state, so that the class-level
# lazy loader is
# executed when next referenced on this instance.
# this is needed in
- # populate_existing() types of scenarios to reset
+ # populate_existing() types of scenarios to reset
# any existing state.
state.reset(dict_, key)
@@ -637,12 +637,12 @@ class ImmediateLoader(AbstractRelationshipLoader):
_get_strategy(LazyLoader).\
init_class_attribute(mapper)
- def setup_query(self, context, entity,
+ def setup_query(self, context, entity,
path, adapter, column_collection=None,
parentmapper=None, **kwargs):
pass
- def create_row_processor(self, context, path,
+ def create_row_processor(self, context, path,
mapper, row, adapter):
def load_immediate(state, dict_, row):
state.get_impl(self.key).get(state, dict_)
@@ -659,8 +659,8 @@ class SubqueryLoader(AbstractRelationshipLoader):
_get_strategy(LazyLoader).\
init_class_attribute(mapper)
- def setup_query(self, context, entity,
- path, adapter,
+ def setup_query(self, context, entity,
+ path, adapter,
column_collection=None,
parentmapper=None, **kwargs):
@@ -677,12 +677,12 @@ class SubqueryLoader(AbstractRelationshipLoader):
else:
effective_entity = self.mapper
- subq_path = context.attributes.get(('subquery_path', None),
+ subq_path = context.attributes.get(('subquery_path', None),
orm_util.PathRegistry.root)
subq_path = subq_path + path
- # if not via query option, check for
+ # if not via query option, check for
# a cycle
if not path.contains(context, "loaderstrategy"):
if self.join_depth:
@@ -695,7 +695,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
self._get_leftmost(subq_path)
orig_query = context.attributes.get(
- ("orig_query", SubqueryLoader),
+ ("orig_query", SubqueryLoader),
context.query)
# generate a new Query from the original, then
@@ -705,7 +705,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
leftmost_attr
)
- # generate another Query that will join the
+ # generate another Query that will join the
# left alias to the target relationships.
# basically doing a longhand
# "from_self()". (from_self() itself not quite industrial
@@ -722,13 +722,13 @@ class SubqueryLoader(AbstractRelationshipLoader):
q = q.order_by(*local_attr)
q = q.add_columns(*local_attr)
- q = self._apply_joins(q, to_join, left_alias,
+ q = self._apply_joins(q, to_join, left_alias,
parent_alias, effective_entity)
q = self._setup_options(q, subq_path, orig_query, effective_entity)
q = self._setup_outermost_orderby(q)
- # add new query to attributes to be picked up
+ # add new query to attributes to be picked up
# by create_row_processor
path.set(context, "subquery", q)
@@ -761,7 +761,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
# to look only for significant columns
q = orig_query._clone().correlate(None)
- # TODO: why does polymporphic etc. require hardcoding
+ # TODO: why does polymporphic etc. require hardcoding
# into _adapt_col_list ? Does query.add_columns(...) work
# with polymorphic loading ?
q._set_entities(q._adapt_col_list(leftmost_attr))
@@ -785,7 +785,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
# figure out what's being joined. a.k.a. the fun part
to_join = [
- (subq_path[i], subq_path[i+1])
+ (subq_path[i], subq_path[i+1])
for i in xrange(0, len(subq_path), 2)
]
@@ -793,21 +793,21 @@ class SubqueryLoader(AbstractRelationshipLoader):
# which needs to be aliased.
if len(to_join) > 1:
- ext = orm_util._extended_entity_info(subq_path[-2])
+ info = inspect(subq_path[-2])
if len(to_join) < 2:
# in the case of a one level eager load, this is the
# leftmost "left_alias".
parent_alias = left_alias
- elif ext.mapper.isa(self.parent):
+ elif info.mapper.isa(self.parent):
# In the case of multiple levels, retrieve
- # it from subq_path[-2]. This is the same as self.parent
- # in the vast majority of cases, and [ticket:2014]
+ # it from subq_path[-2]. This is the same as self.parent
+ # in the vast majority of cases, and [ticket:2014]
# illustrates a case where sub_path[-2] is a subclass
# of self.parent
parent_alias = orm_util.AliasedClass(subq_path[-2])
else:
- # if of_type() were used leading to this relationship,
+ # if of_type() were used leading to this relationship,
# self.parent is more specific than subq_path[-2]
parent_alias = orm_util.AliasedClass(self.parent)
@@ -819,15 +819,15 @@ class SubqueryLoader(AbstractRelationshipLoader):
]
return to_join, local_attr, parent_alias
- def _apply_joins(self, q, to_join, left_alias, parent_alias,
+ def _apply_joins(self, q, to_join, left_alias, parent_alias,
effective_entity):
for i, (mapper, key) in enumerate(to_join):
# we need to use query.join() as opposed to
- # orm.join() here because of the
- # rich behavior it brings when dealing with
+ # orm.join() here because of the
+ # rich behavior it brings when dealing with
# "with_polymorphic" mappers. "aliased"
- # and "from_joinpoint" take care of most of
+ # and "from_joinpoint" take care of most of
# the chaining and aliasing for us.
first = i == 0
@@ -857,7 +857,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
# these will fire relative to subq_path.
q = q._with_current_path(subq_path)
q = q._conditional_options(*orig_query._with_options)
- if orig_query._populate_existing:
+ if orig_query._populate_existing:
q._populate_existing = orig_query._populate_existing
return q
@@ -865,7 +865,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
def _setup_outermost_orderby(self, q):
if self.parent_property.order_by:
# if there's an ORDER BY, alias it the same
- # way joinedloader does, but we have to pull out
+ # way joinedloader does, but we have to pull out
# the "eagerjoin" from the query.
# this really only picks up the "secondary" table
# right now.
@@ -885,7 +885,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
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." %
+ "population - eager loading cannot be applied." %
self)
path = path[self.key]
@@ -902,9 +902,9 @@ class SubqueryLoader(AbstractRelationshipLoader):
collections = path.get(context, "collections")
if collections is None:
collections = dict(
- (k, [v[0] for v in v])
+ (k, [v[0] for v in v])
for k, v in itertools.groupby(
- subq,
+ subq,
lambda x:x[1:]
))
path.set(context, 'collections', collections)
@@ -920,7 +920,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
def _create_collection_loader(self, collections, local_cols):
def load_collection_from_subq(state, dict_, row):
collection = collections.get(
- tuple([row[col] for col in local_cols]),
+ tuple([row[col] for col in local_cols]),
()
)
state.get_impl(self.key).\
@@ -931,7 +931,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
def _create_scalar_loader(self, collections, local_cols):
def load_scalar_from_subq(state, dict_, row):
collection = collections.get(
- tuple([row[col] for col in local_cols]),
+ tuple([row[col] for col in local_cols]),
(None,)
)
if len(collection) > 1:
@@ -951,7 +951,7 @@ log.class_logger(SubqueryLoader)
class JoinedLoader(AbstractRelationshipLoader):
"""Provide loading behavior for a :class:`.RelationshipProperty`
using joined eager loading.
-
+
"""
def __init__(self, parent):
super(JoinedLoader, self).__init__(parent)
@@ -974,8 +974,8 @@ class JoinedLoader(AbstractRelationshipLoader):
with_polymorphic = None
- user_defined_adapter = path.get(context,
- "user_defined_eager_row_processor",
+ user_defined_adapter = path.get(context,
+ "user_defined_eager_row_processor",
False)
if user_defined_adapter is not False:
clauses, adapter, add_to_collection = \
@@ -984,7 +984,7 @@ class JoinedLoader(AbstractRelationshipLoader):
user_defined_adapter
)
else:
- # if not via query option, check for
+ # if not via query option, check for
# a cycle
if not path.contains(context, "loaderstrategy"):
if self.join_depth:
@@ -1000,7 +1000,7 @@ class JoinedLoader(AbstractRelationshipLoader):
)
with_poly_info = path.get(
- context,
+ context,
"path_with_polymorphic",
None
)
@@ -1013,37 +1013,37 @@ class JoinedLoader(AbstractRelationshipLoader):
for value in self.mapper._iterate_polymorphic_properties(
mappers=with_polymorphic):
value.setup(
- context,
- entity,
- path,
- clauses,
- parentmapper=self.mapper,
+ context,
+ entity,
+ path,
+ clauses,
+ parentmapper=self.mapper,
column_collection=add_to_collection,
allow_innerjoin=allow_innerjoin)
- def _get_user_defined_adapter(self, context, entity,
+ def _get_user_defined_adapter(self, context, entity,
path, adapter, user_defined_adapter):
adapter = entity._get_entity_clauses(context.query, context)
if adapter and user_defined_adapter:
user_defined_adapter = user_defined_adapter.wrap(adapter)
- path.set(context, "user_defined_eager_row_processor",
+ path.set(context, "user_defined_eager_row_processor",
user_defined_adapter)
elif adapter:
user_defined_adapter = adapter
- path.set(context, "user_defined_eager_row_processor",
+ path.set(context, "user_defined_eager_row_processor",
user_defined_adapter)
add_to_collection = context.primary_columns
return user_defined_adapter, adapter, add_to_collection
- def _generate_row_adapter(self,
+ def _generate_row_adapter(self,
context, entity, path, adapter,
column_collection, parentmapper, allow_innerjoin
):
with_poly_info = path.get(
- context,
- "path_with_polymorphic",
+ context,
+ "path_with_polymorphic",
None
)
if with_poly_info:
@@ -1051,7 +1051,7 @@ class JoinedLoader(AbstractRelationshipLoader):
else:
to_adapt = orm_util.AliasedClass(self.mapper)
clauses = orm_util.ORMAdapter(
- to_adapt,
+ to_adapt,
equivalents=self.mapper._equivalent_columns,
adapt_required=True)
assert clauses.aliased_class is not None
@@ -1060,7 +1060,7 @@ class JoinedLoader(AbstractRelationshipLoader):
context.multi_row_eager_loaders = True
innerjoin = allow_innerjoin and path.get(context,
- "eager_join_type",
+ "eager_join_type",
self.parent_property.innerjoin)
if not innerjoin:
# if this is an outer join, all eager joins from
@@ -1068,8 +1068,8 @@ class JoinedLoader(AbstractRelationshipLoader):
allow_innerjoin = False
context.create_eager_joins.append(
- (self._create_eager_join, context,
- entity, path, adapter,
+ (self._create_eager_join, context,
+ entity, path, adapter,
parentmapper, clauses, innerjoin)
)
@@ -1077,8 +1077,8 @@ class JoinedLoader(AbstractRelationshipLoader):
path.set(context, "eager_row_processor", clauses)
return clauses, adapter, add_to_collection, allow_innerjoin
- def _create_eager_join(self, context, entity,
- path, adapter, parentmapper,
+ def _create_eager_join(self, context, entity,
+ path, adapter, parentmapper,
clauses, innerjoin):
if parentmapper is None:
@@ -1087,7 +1087,7 @@ class JoinedLoader(AbstractRelationshipLoader):
localparent = parentmapper
# whether or not the Query will wrap the selectable in a subquery,
- # and then attach eager load joins to that (i.e., in the case of
+ # and then attach eager load joins to that (i.e., in the case of
# LIMIT/OFFSET etc.)
should_nest_selectable = context.multi_row_eager_loaders and \
context.query._should_nest_selectable
@@ -1103,7 +1103,7 @@ class JoinedLoader(AbstractRelationshipLoader):
if clause is not None:
# join to an existing FROM clause on the query.
# key it to its list index in the eager_joins dict.
- # Query._compile_context will adapt as needed and
+ # Query._compile_context will adapt as needed and
# append to the FROM clause of the select().
entity_key, default_towrap = index, clause
@@ -1121,14 +1121,14 @@ class JoinedLoader(AbstractRelationshipLoader):
else:
onclause = getattr(
orm_util.AliasedClass(
- self.parent,
+ self.parent,
adapter.selectable
- ),
+ ),
self.key, self.parent_property
)
if onclause is self.parent_property:
- # TODO: this is a temporary hack to
+ # TODO: this is a temporary hack to
# account for polymorphic eager loads where
# the eagerload is referencing via of_type().
join_to_left = True
@@ -1138,10 +1138,10 @@ class JoinedLoader(AbstractRelationshipLoader):
assert clauses.aliased_class is not None
context.eager_joins[entity_key] = eagerjoin = \
orm_util.join(
- towrap,
- clauses.aliased_class,
- onclause,
- join_to_left=join_to_left,
+ towrap,
+ clauses.aliased_class,
+ onclause,
+ join_to_left=join_to_left,
isouter=not innerjoin
)
@@ -1151,11 +1151,11 @@ class JoinedLoader(AbstractRelationshipLoader):
if self.parent_property.secondary is None and \
not parentmapper:
# for parentclause that is the non-eager end of the join,
- # ensure all the parent cols in the primaryjoin are actually
+ # ensure all the parent cols in the primaryjoin are actually
# in the
- # columns clause (i.e. are not deferred), so that aliasing applied
+ # columns clause (i.e. are not deferred), so that aliasing applied
# by the Query propagates those columns outward.
- # This has the effect
+ # This has the effect
# of "undefering" those columns.
for col in sql_util.find_columns(
self.parent_property.primaryjoin):
@@ -1175,12 +1175,12 @@ class JoinedLoader(AbstractRelationshipLoader):
def _create_eager_adapter(self, context, row, adapter, path):
- user_defined_adapter = path.get(context,
- "user_defined_eager_row_processor",
+ user_defined_adapter = path.get(context,
+ "user_defined_eager_row_processor",
False)
if user_defined_adapter is not False:
decorator = user_defined_adapter
- # user defined eagerloads are part of the "primary"
+ # user defined eagerloads are part of the "primary"
# portion of the load.
# the adapters applied to the Query should be honored.
if context.adapter and decorator:
@@ -1196,7 +1196,7 @@ class JoinedLoader(AbstractRelationshipLoader):
self.mapper.identity_key_from_row(row, decorator)
return decorator
except KeyError:
- # no identity key - dont return a row
+ # no identity key - dont return a row
# processor, will cause a degrade to lazy
return False
@@ -1204,14 +1204,14 @@ class JoinedLoader(AbstractRelationshipLoader):
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." %
+ "population - eager loading cannot be applied." %
self)
our_path = path[self.key]
eager_adapter = self._create_eager_adapter(
- context,
- row,
+ context,
+ row,
adapter, our_path)
if eager_adapter is not False:
@@ -1219,7 +1219,7 @@ class JoinedLoader(AbstractRelationshipLoader):
_instance = loading.instance_processor(
self.mapper,
- context,
+ context,
our_path[self.mapper],
eager_adapter)
@@ -1346,8 +1346,8 @@ class LoadEagerFromAliasOption(PropertyOption):
super(LoadEagerFromAliasOption, self).__init__(key)
if alias is not None:
if not isinstance(alias, basestring):
- mapper, alias, is_aliased_class = \
- orm_util._entity_info(alias)
+ info = inspect(alias)
+ alias = info.selectable
self.alias = alias
self.chained = chained
@@ -1357,8 +1357,8 @@ class LoadEagerFromAliasOption(PropertyOption):
(root_mapper, propname) = path.path[-2:]
prop = root_mapper._props[propname]
adapter = query._polymorphic_adapters.get(prop.mapper, None)
- path.setdefault(query,
- "user_defined_eager_row_processor",
+ path.setdefault(query,
+ "user_defined_eager_row_processor",
adapter)
root_mapper, propname = paths[-1].path[-2:]
@@ -1366,31 +1366,31 @@ class LoadEagerFromAliasOption(PropertyOption):
if self.alias is not None:
if isinstance(self.alias, basestring):
self.alias = prop.target.alias(self.alias)
- paths[-1].set(query, "user_defined_eager_row_processor",
- sql_util.ColumnAdapter(self.alias,
+ paths[-1].set(query, "user_defined_eager_row_processor",
+ sql_util.ColumnAdapter(self.alias,
equivalents=prop.mapper._equivalent_columns)
)
else:
if paths[-1].contains(query, "path_with_polymorphic"):
with_poly_info = paths[-1].get(query, "path_with_polymorphic")
adapter = orm_util.ORMAdapter(
- with_poly_info.entity,
+ with_poly_info.entity,
equivalents=prop.mapper._equivalent_columns,
adapt_required=True)
else:
adapter = query._polymorphic_adapters.get(prop.mapper, None)
- paths[-1].set(query, "user_defined_eager_row_processor",
+ paths[-1].set(query, "user_defined_eager_row_processor",
adapter)
def single_parent_validator(desc, prop):
def _do_check(state, value, oldvalue, initiator):
if value is not None and initiator.key == prop.key:
hasparent = initiator.hasparent(attributes.instance_state(value))
- if hasparent and oldvalue is not value:
+ if hasparent and oldvalue is not value:
raise sa_exc.InvalidRequestError(
"Instance %s is already associated with an instance "
"of %s via its %s attribute, and is only allowed a "
- "single parent." %
+ "single parent." %
(orm_util.instance_str(value), state.class_, prop)
)
return value
@@ -1401,8 +1401,8 @@ def single_parent_validator(desc, prop):
def set_(state, value, oldvalue, initiator):
return _do_check(state, value, oldvalue, initiator)
- event.listen(desc, 'append', append, raw=True, retval=True,
+ event.listen(desc, 'append', append, raw=True, retval=True,
active_history=True)
- event.listen(desc, 'set', set_, raw=True, retval=True,
+ event.listen(desc, 'set', set_, raw=True, retval=True,
active_history=True)
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index e9e11ee87..517f1acb4 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -220,7 +220,11 @@ class ORMAdapter(sql_util.ColumnAdapter):
"""
def __init__(self, entity, equivalents=None,
chain_to=None, adapt_required=False):
- self.mapper, selectable, is_aliased_class = _entity_info(entity)
+ info = inspection.inspect(entity)
+
+ self.mapper = info.mapper
+ selectable = info.selectable
+ is_aliased_class = info.is_aliased_class
if is_aliased_class:
self.aliased_class = entity
else:
@@ -446,6 +450,7 @@ class AliasedClass(object):
if alias is None:
alias = mapper._with_polymorphic_selectable.alias(name=name)
self._aliased_insp = AliasedInsp(
+ self,
mapper,
alias,
name,
@@ -490,6 +495,7 @@ class AliasedClass(object):
def __setstate__(self, state):
self._aliased_insp = AliasedInsp(
+ self,
state['mapper'],
state['alias'],
state['name'],
@@ -548,6 +554,7 @@ class AliasedClass(object):
id(self), self.__target.__name__)
AliasedInsp = util.namedtuple("AliasedInsp", [
+ "entity",
"mapper",
"selectable",
"name",
@@ -674,11 +681,19 @@ class _ORMJoin(expression.Join):
if join_to_left:
adapt_from = left.right
else:
- left_mapper, left, left_is_aliased = _entity_info(left)
+ info = inspection.inspect(left)
+ left_mapper = getattr(info, 'mapper', None)
+ left = info.selectable
+ left_is_aliased = getattr(info, 'is_aliased_class', False)
+
if join_to_left and (left_is_aliased or not left_mapper):
adapt_from = left
- right_mapper, right, right_is_aliased = _entity_info(right)
+ info = inspection.inspect(right)
+ right_mapper = getattr(info, 'mapper', None)
+ right = info.selectable
+ right_is_aliased = getattr(info, 'is_aliased_class', False)
+
if right_is_aliased:
adapt_to = right
else:
@@ -939,42 +954,6 @@ def _is_aliased_class(entity):
return insp is not None and \
getattr(insp, "is_aliased_class", False)
-extended_entity_info = util.namedtuple("extended_entity_info", [
- "entity",
- "mapper",
- "selectable",
- "is_aliased_class",
- "with_polymorphic_mappers",
- "with_polymorphic_discriminator"
-])
-def _extended_entity_info(entity):
- insp = inspection.inspect(entity)
- return extended_entity_info(
- entity,
- insp.mapper if not insp.is_selectable else None,
- insp.selectable,
- insp.is_aliased_class if not insp.is_selectable else False,
- insp.with_polymorphic_mappers if not insp.is_selectable else None,
- insp.polymorphic_on if not insp.is_selectable else None
- )
-
-def _entity_info(entity, compile=True):
- """Return mapping information given a class, mapper, or AliasedClass.
-
- Returns 3-tuple of: mapper, mapped selectable, boolean indicating if this
- is an aliased() construct.
-
- If the given entity is not a mapper, mapped class, or aliased construct,
- returns None, the entity, False. This is typically used to allow
- unmapped selectables through.
-
- """
- insp = inspection.inspect(entity)
- return \
- insp.mapper if not insp.is_selectable else None,\
- insp.selectable,\
- insp.is_aliased_class if not insp.is_selectable else False,
-
def _entity_descriptor(entity, key):
"""Return a class attribute given an entity and string name.