summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/query.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm/query.py')
-rw-r--r--lib/sqlalchemy/orm/query.py594
1 files changed, 302 insertions, 292 deletions
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index c340e9856..12e11b26c 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -24,19 +24,19 @@ from itertools import chain
from . import (
attributes, interfaces, object_mapper, persistence,
exc as orm_exc, loading
- )
+)
from .base import _entity_descriptor, _is_aliased_class, \
- _is_mapped_class, _orm_columns, _generative
+ _is_mapped_class, _orm_columns, _generative
from .path_registry import PathRegistry
from .util import (
AliasedClass, ORMAdapter, join as orm_join, with_parent, aliased
- )
+)
from .. import sql, util, log, exc as sa_exc, inspect, inspection
from ..sql.expression import _interpret_as_from
from ..sql import (
- util as sql_util,
- expression, visitors
- )
+ util as sql_util,
+ expression, visitors
+)
from ..sql.base import ColumnCollection
from . import properties
@@ -45,6 +45,7 @@ __all__ = ['Query', 'QueryContext', 'aliased']
_path_registry = PathRegistry.root
+
@inspection._self_inspects
@log.class_logger
class Query(object):
@@ -124,22 +125,22 @@ class Query(object):
if entity not in d:
ext_info = inspect(entity)
if not ext_info.is_aliased_class and \
- ext_info.mapper.with_polymorphic:
+ ext_info.mapper.with_polymorphic:
if ext_info.mapper.mapped_table not in \
- self._polymorphic_adapters:
+ self._polymorphic_adapters:
self._mapper_loads_polymorphically_with(
ext_info.mapper,
sql_util.ColumnAdapter(
- ext_info.selectable,
- ext_info.mapper._equivalent_columns
+ ext_info.selectable,
+ ext_info.mapper._equivalent_columns
)
)
aliased_adapter = None
elif ext_info.is_aliased_class:
aliased_adapter = sql_util.ColumnAdapter(
- ext_info.selectable,
- ext_info.mapper._equivalent_columns
- )
+ ext_info.selectable,
+ ext_info.mapper._equivalent_columns
+ )
else:
aliased_adapter = None
@@ -163,17 +164,17 @@ class Query(object):
info = inspect(from_obj)
if hasattr(info, 'mapper') and \
- (info.is_mapper or info.is_aliased_class):
+ (info.is_mapper or info.is_aliased_class):
self._select_from_entity = from_obj
if set_base_alias:
raise sa_exc.ArgumentError(
- "A selectable (FromClause) instance is "
- "expected when the base alias is being set.")
+ "A selectable (FromClause) instance is "
+ "expected when the base alias is being set.")
fa.append(info.selectable)
elif not info.is_selectable:
raise sa_exc.ArgumentError(
- "argument is not a mapped class, mapper, "
- "aliased(), or FromClause instance.")
+ "argument is not a mapped class, mapper, "
+ "aliased(), or FromClause instance.")
else:
if isinstance(from_obj, expression.SelectBase):
from_obj = from_obj.alias()
@@ -184,11 +185,11 @@ class Query(object):
self._from_obj = tuple(fa)
if set_base_alias and \
- len(self._from_obj) == 1 and \
- isinstance(select_from_alias, expression.Alias):
+ len(self._from_obj) == 1 and \
+ isinstance(select_from_alias, expression.Alias):
equivs = self.__all_equivs()
self._from_obj_alias = sql_util.ColumnAdapter(
- self._from_obj[0], equivs)
+ self._from_obj[0], equivs)
def _reset_polymorphic_adapter(self, mapper):
for m2 in mapper._with_polymorphic_mappers:
@@ -216,11 +217,11 @@ class Query(object):
def _adapt_col_list(self, cols):
return [
- self._adapt_clause(
- expression._literal_as_text(o),
- True, True)
- for o in cols
- ]
+ self._adapt_clause(
+ expression._literal_as_text(o),
+ True, True)
+ for o in cols
+ ]
@_generative()
def _adapt_all_clauses(self):
@@ -270,18 +271,18 @@ class Query(object):
# if 'orm only', look for ORM annotations
# in the element before adapting.
if not _orm_only or \
- '_orm_adapt' in elem._annotations or \
- "parententity" in elem._annotations:
+ '_orm_adapt' in elem._annotations or \
+ "parententity" in elem._annotations:
e = adapter(elem)
if e is not None:
return e
return visitors.replacement_traverse(
- clause,
- {},
- replace
- )
+ clause,
+ {},
+ replace
+ )
def _entity_zero(self):
return self._entities[0]
@@ -311,26 +312,26 @@ class Query(object):
def _only_mapper_zero(self, rationale=None):
if len(self._entities) > 1:
raise sa_exc.InvalidRequestError(
- rationale or
- "This operation requires a Query "
- "against a single mapper."
- )
+ rationale or
+ "This operation requires a Query "
+ "against a single mapper."
+ )
return self._mapper_zero()
def _only_full_mapper_zero(self, methname):
if self._entities != [self._primary_entity]:
raise sa_exc.InvalidRequestError(
- "%s() can only be used against "
- "a single mapped class." % methname)
+ "%s() can only be used against "
+ "a single mapped class." % methname)
return self._primary_entity.entity_zero
def _only_entity_zero(self, rationale=None):
if len(self._entities) > 1:
raise sa_exc.InvalidRequestError(
- rationale or
- "This operation requires a Query "
- "against a single mapper."
- )
+ rationale or
+ "This operation requires a Query "
+ "against a single mapper."
+ )
return self._entity_zero()
def __all_equivs(self):
@@ -340,7 +341,8 @@ class Query(object):
return equivs
def _get_condition(self):
- return self._no_criterion_condition("get", order_by=False, distinct=False)
+ return self._no_criterion_condition(
+ "get", order_by=False, distinct=False)
def _get_existing_condition(self):
self._no_criterion_assertion("get", order_by=False, distinct=False)
@@ -354,8 +356,8 @@ class Query(object):
self._group_by or (order_by and self._order_by) or \
(distinct and self._distinct):
raise sa_exc.InvalidRequestError(
- "Query.%s() being called on a "
- "Query with existing criterion. " % meth)
+ "Query.%s() being called on a "
+ "Query with existing criterion. " % meth)
def _no_criterion_condition(self, meth, order_by=True, distinct=True):
self._no_criterion_assertion(meth, order_by, distinct)
@@ -369,8 +371,8 @@ class Query(object):
return
if self._order_by:
raise sa_exc.InvalidRequestError(
- "Query.%s() being called on a "
- "Query with existing criterion. " % meth)
+ "Query.%s() being called on a "
+ "Query with existing criterion. " % meth)
self._no_criterion_condition(meth)
def _no_statement_condition(self, meth):
@@ -411,9 +413,9 @@ class Query(object):
)
def _get_options(self, populate_existing=None,
- version_check=None,
- only_load_props=None,
- refresh_state=None):
+ version_check=None,
+ only_load_props=None,
+ refresh_state=None):
if populate_existing:
self._populate_existing = populate_existing
if version_check:
@@ -441,11 +443,10 @@ class Query(object):
"""
stmt = self._compile_context(labels=self._with_labels).\
- statement
+ statement
if self._params:
stmt = stmt.params(self._params)
-
# TODO: there's no tests covering effects of
# the annotation not being there
return stmt._annotate({'no_replacement_traverse': True})
@@ -662,9 +663,9 @@ class Query(object):
@_generative(_no_clauseelement_condition)
def with_polymorphic(self,
- cls_or_mappers,
- selectable=None,
- polymorphic_on=None):
+ cls_or_mappers,
+ selectable=None,
+ polymorphic_on=None):
"""Load columns for inheriting classes.
:meth:`.Query.with_polymorphic` applies transformations
@@ -692,13 +693,13 @@ class Query(object):
if not self._primary_entity:
raise sa_exc.InvalidRequestError(
- "No primary mapper set up for this Query.")
+ "No primary mapper set up for this Query.")
entity = self._entities[0]._clone()
self._entities = [entity] + self._entities[1:]
entity.set_with_polymorphic(self,
- cls_or_mappers,
- selectable=selectable,
- polymorphic_on=polymorphic_on)
+ cls_or_mappers,
+ selectable=selectable,
+ polymorphic_on=polymorphic_on)
@_generative()
def yield_per(self, count):
@@ -717,15 +718,16 @@ class Query(object):
Also note that while :meth:`~sqlalchemy.orm.query.Query.yield_per`
will set the ``stream_results`` execution option to True, currently
- this is only understood by :mod:`~sqlalchemy.dialects.postgresql.psycopg2` dialect
- which will stream results using server side cursors instead of pre-buffer
- all rows for this query. Other DBAPIs pre-buffer all rows before
- making them available.
+ this is only understood by
+ :mod:`~sqlalchemy.dialects.postgresql.psycopg2` dialect which will
+ stream results using server side cursors instead of pre-buffer all
+ rows for this query. Other DBAPIs pre-buffer all rows before making
+ them available.
"""
self._yield_per = count
self._execution_options = self._execution_options.union(
- {"stream_results": True})
+ {"stream_results": True})
def get(self, ident):
"""Return an instance based on the given primary key identifier,
@@ -795,9 +797,9 @@ class Query(object):
if len(ident) != len(mapper.primary_key):
raise sa_exc.InvalidRequestError(
- "Incorrect number of values in identifier to formulate "
- "primary key for query.get(); primary key columns are %s" %
- ','.join("'%s'" % c for c in mapper.primary_key))
+ "Incorrect number of values in identifier to formulate "
+ "primary key for query.get(); primary key columns are %s" %
+ ','.join("'%s'" % c for c in mapper.primary_key))
key = mapper.identity_key_from_primary_key(ident)
@@ -839,9 +841,9 @@ class Query(object):
"""
self._correlate = self._correlate.union(
- _interpret_as_from(s)
- if s is not None else None
- for s in args)
+ _interpret_as_from(s)
+ if s is not None else None
+ for s in args)
@_generative()
def autoflush(self, setting):
@@ -900,17 +902,17 @@ class Query(object):
for prop in mapper.iterate_properties:
if isinstance(prop, properties.RelationshipProperty) and \
- prop.mapper is self._mapper_zero():
+ prop.mapper is self._mapper_zero():
property = prop
break
else:
raise sa_exc.InvalidRequestError(
- "Could not locate a property which relates instances "
- "of class '%s' to instances of class '%s'" %
- (
- self._mapper_zero().class_.__name__,
- instance.__class__.__name__)
- )
+ "Could not locate a property which relates instances "
+ "of class '%s' to instances of class '%s'" %
+ (
+ self._mapper_zero().class_.__name__,
+ instance.__class__.__name__)
+ )
return self.filter(with_parent(instance, property))
@@ -943,8 +945,8 @@ class Query(object):
"""
fromclause = self.with_labels().enable_eagerloads(False).\
- _set_enable_single_crit(False).\
- statement.correlate(None)
+ _set_enable_single_crit(False).\
+ statement.correlate(None)
q = self._from_selectable(fromclause)
if entities:
q._set_entities(entities)
@@ -1039,8 +1041,9 @@ class Query(object):
self._set_entity_selectables(self._entities[l:])
@util.pending_deprecation("0.7",
- ":meth:`.add_column` is superseded by :meth:`.add_columns`",
- False)
+ ":meth:`.add_column` is superseded "
+ "by :meth:`.add_columns`",
+ False)
def add_column(self, column):
"""Add a column expression to the list of result columns to be
returned.
@@ -1205,8 +1208,8 @@ class Query(object):
kwargs.update(args[0])
elif len(args) > 0:
raise sa_exc.ArgumentError(
- "params() takes zero or one positional argument, "
- "which is a dictionary.")
+ "params() takes zero or one positional argument, "
+ "which is a dictionary.")
self._params = self._params.copy()
self._params.update(kwargs)
@@ -1246,7 +1249,6 @@ class Query(object):
else:
self._criterion = criterion
-
def filter_by(self, **kwargs):
"""apply the given filtering criterion to a copy
of this :class:`.Query`, using keyword expressions.
@@ -1271,7 +1273,7 @@ class Query(object):
"""
clauses = [_entity_descriptor(self._joinpoint_zero(), key) == value
- for key, value in kwargs.items()]
+ for key, value in kwargs.items()]
return self.filter(sql.and_(*clauses))
@_generative(_no_statement_condition, _no_limit_offset)
@@ -1324,7 +1326,8 @@ class Query(object):
"""apply a HAVING criterion to the query and return the
newly resulting :class:`.Query`.
- :meth:`~.Query.having` is used in conjunction with :meth:`~.Query.group_by`.
+ :meth:`~.Query.having` is used in conjunction with
+ :meth:`~.Query.group_by`.
HAVING criterion makes it possible to use filters on aggregate
functions like COUNT, SUM, AVG, MAX, and MIN, eg.::
@@ -1342,8 +1345,8 @@ class Query(object):
if criterion is not None and \
not isinstance(criterion, sql.ClauseElement):
raise sa_exc.ArgumentError(
- "having() argument must be of type "
- "sqlalchemy.sql.ClauseElement or string")
+ "having() argument must be of type "
+ "sqlalchemy.sql.ClauseElement or string")
criterion = self._adapt_clause(criterion, True, True)
@@ -1391,7 +1394,7 @@ class Query(object):
"""
return self._from_selectable(
- expression.union(*([self] + list(q))))
+ expression.union(*([self] + list(q))))
def union_all(self, *q):
"""Produce a UNION ALL of this Query against one or more queries.
@@ -1401,8 +1404,8 @@ class Query(object):
"""
return self._from_selectable(
- expression.union_all(*([self] + list(q)))
- )
+ expression.union_all(*([self] + list(q)))
+ )
def intersect(self, *q):
"""Produce an INTERSECT of this Query against one or more queries.
@@ -1412,8 +1415,8 @@ class Query(object):
"""
return self._from_selectable(
- expression.intersect(*([self] + list(q)))
- )
+ expression.intersect(*([self] + list(q)))
+ )
def intersect_all(self, *q):
"""Produce an INTERSECT ALL of this Query against one or more queries.
@@ -1423,8 +1426,8 @@ class Query(object):
"""
return self._from_selectable(
- expression.intersect_all(*([self] + list(q)))
- )
+ expression.intersect_all(*([self] + list(q)))
+ )
def except_(self, *q):
"""Produce an EXCEPT of this Query against one or more queries.
@@ -1434,8 +1437,8 @@ class Query(object):
"""
return self._from_selectable(
- expression.except_(*([self] + list(q)))
- )
+ expression.except_(*([self] + list(q)))
+ )
def except_all(self, *q):
"""Produce an EXCEPT ALL of this Query against one or more queries.
@@ -1445,8 +1448,8 @@ class Query(object):
"""
return self._from_selectable(
- expression.except_all(*([self] + list(q)))
- )
+ expression.except_all(*([self] + list(q)))
+ )
def join(self, *props, **kwargs):
"""Create a SQL JOIN against this :class:`.Query` object's criterion
@@ -1456,8 +1459,8 @@ class Query(object):
Consider a mapping between two classes ``User`` and ``Address``,
with a relationship ``User.addresses`` representing a collection
- of ``Address`` objects associated with each ``User``. The most common
- usage of :meth:`~.Query.join` is to create a JOIN along this
+ of ``Address`` objects associated with each ``User``. The most
+ common usage of :meth:`~.Query.join` is to create a JOIN along this
relationship, using the ``User.addresses`` attribute as an indicator
for how this should occur::
@@ -1683,8 +1686,8 @@ class Query(object):
:ref:`ormtutorial_joins` in the ORM tutorial.
- :ref:`inheritance_toplevel` for details on how :meth:`~.Query.join`
- is used for inheritance relationships.
+ :ref:`inheritance_toplevel` for details on how
+ :meth:`~.Query.join` is used for inheritance relationships.
:func:`.orm.join` - a standalone ORM-level join function,
used internally by :meth:`.Query.join`, which in previous
@@ -1692,13 +1695,13 @@ class Query(object):
"""
aliased, from_joinpoint = kwargs.pop('aliased', False),\
- kwargs.pop('from_joinpoint', False)
+ kwargs.pop('from_joinpoint', False)
if kwargs:
raise TypeError("unknown arguments: %s" %
- ','.join(kwargs.keys))
+ ','.join(kwargs.keys))
return self._join(props,
- outerjoin=False, create_aliases=aliased,
- from_joinpoint=from_joinpoint)
+ outerjoin=False, create_aliases=aliased,
+ from_joinpoint=from_joinpoint)
def outerjoin(self, *props, **kwargs):
"""Create a left outer join against this ``Query`` object's criterion
@@ -1708,13 +1711,13 @@ class Query(object):
"""
aliased, from_joinpoint = kwargs.pop('aliased', False), \
- kwargs.pop('from_joinpoint', False)
+ kwargs.pop('from_joinpoint', False)
if kwargs:
raise TypeError("unknown arguments: %s" %
- ','.join(kwargs))
+ ','.join(kwargs))
return self._join(props,
- outerjoin=True, create_aliases=aliased,
- from_joinpoint=from_joinpoint)
+ outerjoin=True, create_aliases=aliased,
+ from_joinpoint=from_joinpoint)
def _update_joinpoint(self, jp):
self._joinpoint = jp
@@ -1740,9 +1743,9 @@ class Query(object):
if len(keys) == 2 and \
isinstance(keys[0], (expression.FromClause,
- type, AliasedClass)) and \
+ type, AliasedClass)) and \
isinstance(keys[1], (str, expression.ClauseElement,
- interfaces.PropComparator)):
+ interfaces.PropComparator)):
# detect 2-arg form of join and
# convert to a tuple.
keys = (keys,)
@@ -1761,7 +1764,8 @@ class Query(object):
# is a little bit of legacy behavior still at work here
# which means they might be in either order. may possibly
# lock this down to (right_entity, onclause) in 0.6.
- if isinstance(arg1, (interfaces.PropComparator, util.string_types)):
+ if isinstance(
+ arg1, (interfaces.PropComparator, util.string_types)):
right_entity, onclause = arg2, arg1
else:
right_entity, onclause = arg1, arg2
@@ -1777,7 +1781,7 @@ class Query(object):
# check for q.join(Class.propname, from_joinpoint=True)
# and Class is that of the current joinpoint
elif from_joinpoint and \
- isinstance(onclause, interfaces.PropComparator):
+ isinstance(onclause, interfaces.PropComparator):
left_entity = onclause._parententity
info = inspect(self._joinpoint_zero())
@@ -1789,7 +1793,7 @@ class Query(object):
if left_mapper is left_entity:
left_entity = self._joinpoint_zero()
descriptor = _entity_descriptor(left_entity,
- onclause.key)
+ onclause.key)
onclause = descriptor
if isinstance(onclause, interfaces.PropComparator):
@@ -1804,7 +1808,7 @@ class Query(object):
left_entity = onclause._parententity
prop = onclause.property
- if not isinstance(onclause, attributes.QueryableAttribute):
+ if not isinstance(onclause, attributes.QueryableAttribute):
onclause = prop
if not create_aliases:
@@ -1829,10 +1833,9 @@ class Query(object):
raise NotImplementedError("query.join(a==b) not supported.")
self._join_left_to_right(
- left_entity,
- right_entity, onclause,
- outerjoin, create_aliases, prop)
-
+ left_entity,
+ right_entity, onclause,
+ outerjoin, create_aliases, prop)
def _join_left_to_right(self, left, right,
onclause, outerjoin, create_aliases, prop):
@@ -1848,48 +1851,49 @@ class Query(object):
if left is None:
raise sa_exc.InvalidRequestError(
- "Don't know how to join from %s; please use "
- "select_from() to establish the left "
- "entity/selectable of this join" % self._entities[0])
+ "Don't know how to join from %s; please use "
+ "select_from() to establish the left "
+ "entity/selectable of this join" % self._entities[0])
if left is right and \
not create_aliases:
raise sa_exc.InvalidRequestError(
- "Can't construct a join from %s to %s, they "
- "are the same entity" %
- (left, right))
+ "Can't construct a join from %s to %s, they "
+ "are the same entity" %
+ (left, right))
l_info = inspect(left)
r_info = inspect(right)
-
overlap = False
if not create_aliases:
right_mapper = getattr(r_info, "mapper", None)
# if the target is a joined inheritance mapping,
# be more liberal about auto-aliasing.
if right_mapper and (
- right_mapper.with_polymorphic or
- isinstance(right_mapper.mapped_table, expression.Join)
- ):
+ right_mapper.with_polymorphic or
+ isinstance(right_mapper.mapped_table, expression.Join)
+ ):
for from_obj in self._from_obj or [l_info.selectable]:
- if sql_util.selectables_overlap(l_info.selectable, from_obj) and \
- sql_util.selectables_overlap(from_obj, r_info.selectable):
+ if sql_util.selectables_overlap(
+ l_info.selectable, from_obj) and \
+ sql_util.selectables_overlap(
+ from_obj, r_info.selectable):
overlap = True
break
- elif sql_util.selectables_overlap(l_info.selectable, r_info.selectable):
+ elif sql_util.selectables_overlap(l_info.selectable,
+ r_info.selectable):
overlap = True
-
if overlap and l_info.selectable is r_info.selectable:
raise sa_exc.InvalidRequestError(
- "Can't join table/selectable '%s' to itself" %
- l_info.selectable)
+ "Can't join table/selectable '%s' to itself" %
+ l_info.selectable)
right, onclause = self._prepare_right_side(
- r_info, right, onclause,
- create_aliases,
- prop, overlap)
+ r_info, right, onclause,
+ create_aliases,
+ prop, overlap)
# if joining on a MapperProperty path,
# track the path to prevent redundant joins
@@ -1904,7 +1908,7 @@ class Query(object):
self._join_to_left(l_info, left, right, onclause, outerjoin)
def _prepare_right_side(self, r_info, right, onclause, create_aliases,
- prop, overlap):
+ prop, overlap):
info = r_info
right_mapper, right_selectable, right_is_aliased = \
@@ -1918,8 +1922,8 @@ class Query(object):
if right_mapper and prop and \
not right_mapper.common_parent(prop.mapper):
raise sa_exc.InvalidRequestError(
- "Join target %s does not correspond to "
- "the right side of join condition %s" % (right, onclause)
+ "Join target %s does not correspond to "
+ "the right side of join condition %s" % (right, onclause)
)
if not right_mapper and prop:
@@ -1929,11 +1933,11 @@ class Query(object):
if right_mapper and right is right_selectable:
if not right_selectable.is_derived_from(
- right_mapper.mapped_table):
+ right_mapper.mapped_table):
raise sa_exc.InvalidRequestError(
"Selectable '%s' is not derived from '%s'" %
(right_selectable.description,
- right_mapper.mapped_table.description))
+ right_mapper.mapped_table.description))
if isinstance(right_selectable, expression.SelectBase):
# TODO: this isn't even covered now!
@@ -1943,16 +1947,16 @@ class Query(object):
right = aliased(right_mapper, right_selectable)
aliased_entity = right_mapper and \
- not right_is_aliased and \
- (
- right_mapper.with_polymorphic and isinstance(
- right_mapper._with_polymorphic_selectable,
- expression.Alias)
- or
- overlap # test for overlap:
- # orm/inheritance/relationships.py
- # SelfReferentialM2MTest
- )
+ not right_is_aliased and \
+ (
+ right_mapper.with_polymorphic and isinstance(
+ right_mapper._with_polymorphic_selectable,
+ expression.Alias)
+ or
+ overlap # test for overlap:
+ # orm/inheritance/relationships.py
+ # SelfReferentialM2MTest
+ )
if not need_adapter and (create_aliases or aliased_entity):
right = aliased(right, flat=True)
@@ -1962,10 +1966,11 @@ class Query(object):
# apply an adapter to all subsequent filter() calls
# until reset_joinpoint() is called.
if need_adapter:
- self._filter_aliases = ORMAdapter(right,
- equivalents=right_mapper and
- right_mapper._equivalent_columns or {},
- chain_to=self._filter_aliases)
+ self._filter_aliases = ORMAdapter(
+ right,
+ equivalents=right_mapper and
+ right_mapper._equivalent_columns or {},
+ chain_to=self._filter_aliases)
# if the onclause is a ClauseElement, adapt it with any
# adapters that are in place right now
@@ -1978,12 +1983,12 @@ class Query(object):
# set are also adapted.
if aliased_entity and not create_aliases:
self._mapper_loads_polymorphically_with(
- right_mapper,
- ORMAdapter(
- right,
- equivalents=right_mapper._equivalent_columns
- )
- )
+ right_mapper,
+ ORMAdapter(
+ right,
+ equivalents=right_mapper._equivalent_columns
+ )
+ )
return right, onclause
@@ -1994,22 +1999,22 @@ class Query(object):
if self._from_obj:
replace_clause_index, clause = sql_util.find_join_source(
- self._from_obj,
- left_selectable)
+ self._from_obj,
+ left_selectable)
if clause is not None:
try:
clause = orm_join(clause,
- right,
- onclause, isouter=outerjoin)
+ right,
+ onclause, isouter=outerjoin)
except sa_exc.ArgumentError as ae:
raise sa_exc.InvalidRequestError(
- "Could not find a FROM clause to join from. "
- "Tried joining to %s, but got: %s" % (right, ae))
+ "Could not find a FROM clause to join from. "
+ "Tried joining to %s, but got: %s" % (right, ae))
self._from_obj = \
- self._from_obj[:replace_clause_index] + \
- (clause, ) + \
- self._from_obj[replace_clause_index + 1:]
+ self._from_obj[:replace_clause_index] + \
+ (clause, ) + \
+ self._from_obj[replace_clause_index + 1:]
return
if left_mapper:
@@ -2027,8 +2032,8 @@ class Query(object):
clause = orm_join(clause, right, onclause, isouter=outerjoin)
except sa_exc.ArgumentError as ae:
raise sa_exc.InvalidRequestError(
- "Could not find a FROM clause to join from. "
- "Tried joining to %s, but got: %s" % (right, ae))
+ "Could not find a FROM clause to join from. "
+ "Tried joining to %s, but got: %s" % (right, ae))
self._from_obj = self._from_obj + (clause,)
def _reset_joinpoint(self):
@@ -2186,14 +2191,14 @@ class Query(object):
start, stop, step = util.decode_slice(item)
if isinstance(stop, int) and \
- isinstance(start, int) and \
- stop - start <= 0:
+ isinstance(start, int) and \
+ stop - start <= 0:
return []
# perhaps we should execute a count() here so that we
# can still use LIMIT/OFFSET ?
elif (isinstance(start, int) and start < 0) \
- or (isinstance(stop, int) and stop < 0):
+ or (isinstance(stop, int) and stop < 0):
return list(self)[item]
res = self.slice(start, stop)
@@ -2310,11 +2315,11 @@ class Query(object):
statement = sql.text(statement)
if not isinstance(statement,
- (expression.TextClause,
- expression.SelectBase)):
+ (expression.TextClause,
+ expression.SelectBase)):
raise sa_exc.ArgumentError(
- "from_statement accepts text(), select(), "
- "and union() objects only.")
+ "from_statement accepts text(), select(), "
+ "and union() objects only.")
self._statement = statement
@@ -2408,16 +2413,16 @@ class Query(object):
def _connection_from_session(self, **kw):
conn = self.session.connection(
- **kw)
+ **kw)
if self._execution_options:
conn = conn.execution_options(**self._execution_options)
return conn
def _execute_and_instances(self, querycontext):
conn = self._connection_from_session(
- mapper=self._mapper_zero_or_none(),
- clause=querycontext.statement,
- close_with_result=True)
+ mapper=self._mapper_zero_or_none(),
+ clause=querycontext.statement,
+ close_with_result=True)
result = conn.execute(querycontext.statement, self._params)
return loading.instances(self, result, querycontext)
@@ -2553,7 +2558,7 @@ class Query(object):
# .with_only_columns() after we have a core select() so that
# we get just "SELECT 1" without any entities.
return sql.exists(self.add_columns('1').with_labels().
- statement.with_only_columns(['1']))
+ statement.with_only_columns(['1']))
def count(self):
"""Return a count of rows this Query would return.
@@ -2629,10 +2634,11 @@ class Query(object):
This method has several key caveats:
- * The method does **not** offer in-Python cascading of relationships - it
- is assumed that ON DELETE CASCADE/SET NULL/etc. is configured for any foreign key
- references which require it, otherwise the database may emit an
- integrity violation if foreign key references are being enforced.
+ * The method does **not** offer in-Python cascading of relationships
+ - it is assumed that ON DELETE CASCADE/SET NULL/etc. is configured
+ for any foreign key references which require it, otherwise the
+ database may emit an integrity violation if foreign key references
+ are being enforced.
After the DELETE, dependent objects in the :class:`.Session` which
were impacted by an ON DELETE may not contain the current
@@ -2641,8 +2647,8 @@ class Query(object):
which normally occurs upon :meth:`.Session.commit` or can be forced
by using :meth:`.Session.expire_all`. Accessing an expired object
whose row has been deleted will invoke a SELECT to locate the
- row; when the row is not found, an :class:`~sqlalchemy.orm.exc.ObjectDeletedError`
- is raised.
+ row; when the row is not found, an
+ :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised.
* The :meth:`.MapperEvents.before_delete` and
:meth:`.MapperEvents.after_delete`
@@ -2657,10 +2663,10 @@ class Query(object):
:ref:`inserts_and_updates` - Core SQL tutorial
"""
- #TODO: cascades need handling.
+ # TODO: cascades need handling.
delete_op = persistence.BulkDelete.factory(
- self, synchronize_session)
+ self, synchronize_session)
delete_op.exec_()
return delete_op.rowcount
@@ -2698,9 +2704,9 @@ class Query(object):
This method has several key caveats:
- * The method does **not** offer in-Python cascading of relationships - it
- is assumed that ON UPDATE CASCADE is configured for any foreign key
- references which require it, otherwise the database may emit an
+ * The method does **not** offer in-Python cascading of relationships
+ - it is assumed that ON UPDATE CASCADE is configured for any foreign
+ key references which require it, otherwise the database may emit an
integrity violation if foreign key references are being enforced.
After the UPDATE, dependent objects in the :class:`.Session` which
@@ -2709,16 +2715,16 @@ class Query(object):
which normally occurs upon :meth:`.Session.commit` or can be forced
by using :meth:`.Session.expire_all`.
- * As of 0.8, this method will support multiple table updates, as detailed
- in :ref:`multi_table_updates`, and this behavior does extend to support
- updates of joined-inheritance and other multiple table mappings. However,
- the **join condition of an inheritance mapper is currently not
- automatically rendered**.
- Care must be taken in any multiple-table update to explicitly include
- the joining condition between those tables, even in mappings where
- this is normally automatic.
- E.g. if a class ``Engineer`` subclasses ``Employee``, an UPDATE of the
- ``Engineer`` local table using criteria against the ``Employee``
+ * As of 0.8, this method will support multiple table updates, as
+ detailed in :ref:`multi_table_updates`, and this behavior does
+ extend to support updates of joined-inheritance and other multiple
+ table mappings. However, the **join condition of an inheritance
+ mapper is currently not automatically rendered**.
+ Care must be taken in any multiple-table update to explicitly
+ include the joining condition between those tables, even in mappings
+ where this is normally automatic.
+ E.g. if a class ``Engineer`` subclasses ``Employee``, an UPDATE of
+ the ``Engineer`` local table using criteria against the ``Employee``
local table might look like::
session.query(Engineer).\\
@@ -2740,18 +2746,17 @@ class Query(object):
"""
- #TODO: value keys need to be mapped to corresponding sql cols and
+ # TODO: value keys need to be mapped to corresponding sql cols and
# instr.attr.s to string keys
- #TODO: updates of manytoone relationships need to be converted to
+ # TODO: updates of manytoone relationships need to be converted to
# fk assignments
- #TODO: cascades need handling.
+ # TODO: cascades need handling.
update_op = persistence.BulkUpdate.factory(
- self, synchronize_session, values)
+ self, synchronize_session, values)
update_op.exec_()
return update_op.rowcount
-
def _compile_context(self, labels=True):
context = QueryContext(self)
@@ -2784,13 +2789,13 @@ class Query(object):
if not context.primary_columns:
if self._only_load_props:
raise sa_exc.InvalidRequestError(
- "No column-based properties specified for "
- "refresh operation. Use session.expire() "
- "to reload collections and related items.")
+ "No column-based properties specified for "
+ "refresh operation. Use session.expire() "
+ "to reload collections and related items.")
else:
raise sa_exc.InvalidRequestError(
- "Query contains no columns with which to "
- "SELECT from.")
+ "Query contains no columns with which to "
+ "SELECT from.")
if context.multi_row_eager_loaders and self._should_nest_selectable:
context.statement = self._compound_eager_statement(context)
@@ -2805,26 +2810,26 @@ class Query(object):
if context.order_by:
order_by_col_expr = list(
- chain(*[
- sql_util.unwrap_order_by(o)
- for o in context.order_by
- ])
- )
+ chain(*[
+ sql_util.unwrap_order_by(o)
+ for o in context.order_by
+ ])
+ )
else:
context.order_by = None
order_by_col_expr = []
inner = sql.select(
- context.primary_columns + order_by_col_expr,
- context.whereclause,
- from_obj=context.froms,
- use_labels=context.labels,
- # TODO: this order_by is only needed if
- # LIMIT/OFFSET is present in self._select_args,
- # else the application on the outside is enough
- order_by=context.order_by,
- **self._select_args
- )
+ context.primary_columns + order_by_col_expr,
+ context.whereclause,
+ from_obj=context.froms,
+ use_labels=context.labels,
+ # TODO: this order_by is only needed if
+ # LIMIT/OFFSET is present in self._select_args,
+ # else the application on the outside is enough
+ order_by=context.order_by,
+ **self._select_args
+ )
for hint in self._with_hints:
inner = inner.with_hint(*hint)
@@ -2839,8 +2844,8 @@ class Query(object):
context.adapter = sql_util.ColumnAdapter(inner, equivs)
statement = sql.select(
- [inner] + context.secondary_columns,
- use_labels=context.labels)
+ [inner] + context.secondary_columns,
+ use_labels=context.labels)
statement._for_update_arg = context._for_update_arg
@@ -2850,8 +2855,8 @@ class Query(object):
# giving us a marker as to where the "splice point" of
# the join should be
from_clause = sql_util.splice_joins(
- from_clause,
- eager_join, eager_join.stop_on)
+ from_clause,
+ eager_join, eager_join.stop_on)
statement.append_from(from_clause)
@@ -2871,24 +2876,24 @@ class Query(object):
if self._distinct and context.order_by:
order_by_col_expr = list(
- chain(*[
- sql_util.unwrap_order_by(o)
- for o in context.order_by
- ])
- )
+ chain(*[
+ sql_util.unwrap_order_by(o)
+ for o in context.order_by
+ ])
+ )
context.primary_columns += order_by_col_expr
context.froms += tuple(context.eager_joins.values())
statement = sql.select(
- context.primary_columns +
- context.secondary_columns,
- context.whereclause,
- from_obj=context.froms,
- use_labels=context.labels,
- order_by=context.order_by,
- **self._select_args
- )
+ context.primary_columns +
+ context.secondary_columns,
+ context.whereclause,
+ from_obj=context.froms,
+ use_labels=context.labels,
+ order_by=context.order_by,
+ **self._select_args
+ )
statement._for_update_arg = context._for_update_arg
for hint in self._with_hints:
@@ -2920,14 +2925,15 @@ class Query(object):
single_crit = adapter.traverse(single_crit)
single_crit = self._adapt_clause(single_crit, False, False)
context.whereclause = sql.and_(
- sql.True_._ifnone(context.whereclause),
- single_crit)
+ sql.True_._ifnone(context.whereclause),
+ single_crit)
def __str__(self):
return str(self._compile_context().statement)
from ..sql.selectable import ForUpdateArg
+
class LockmodeArg(ForUpdateArg):
@classmethod
def parse_legacy_query(self, mode):
@@ -2944,10 +2950,11 @@ class LockmodeArg(ForUpdateArg):
read = False
else:
raise sa_exc.ArgumentError(
- "Unknown with_lockmode argument: %r" % mode)
+ "Unknown with_lockmode argument: %r" % mode)
return LockmodeArg(read=read, nowait=nowait)
+
class _QueryEntity(object):
"""represent an entity column returned within a Query result."""
@@ -2955,7 +2962,7 @@ class _QueryEntity(object):
if cls is _QueryEntity:
entity = args[1]
if not isinstance(entity, util.string_types) and \
- _is_mapped_class(entity):
+ _is_mapped_class(entity):
cls = _MapperEntity
elif isinstance(entity, Bundle):
cls = _BundleEntity
@@ -2989,7 +2996,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.polymorphic_on
+ ext_info.polymorphic_on
self.entity_zero = ext_info
if ext_info.is_aliased_class:
self._label_name = self.entity_zero.name
@@ -2999,7 +3006,7 @@ class _MapperEntity(_QueryEntity):
self.custom_rows = bool(self.mapper.dispatch.append_result)
def set_with_polymorphic(self, query, cls_or_mappers,
- selectable, polymorphic_on):
+ selectable, polymorphic_on):
"""Receive an update from a call to query.with_polymorphic().
Note the newer style of using a free standing with_polymporphic()
@@ -3010,23 +3017,23 @@ class _MapperEntity(_QueryEntity):
if self.is_aliased_class:
# TODO: invalidrequest ?
raise NotImplementedError(
- "Can't use with_polymorphic() against "
- "an Aliased object"
- )
+ "Can't use with_polymorphic() against "
+ "an Aliased object"
+ )
if cls_or_mappers is None:
query._reset_polymorphic_adapter(self.mapper)
return
mappers, from_obj = self.mapper._with_polymorphic_args(
- cls_or_mappers, selectable)
+ cls_or_mappers, selectable)
self._with_polymorphic = mappers
self._polymorphic_discriminator = polymorphic_on
self.selectable = from_obj
- query._mapper_loads_polymorphically_with(self.mapper,
- sql_util.ColumnAdapter(from_obj,
- self.mapper._equivalent_columns))
+ query._mapper_loads_polymorphically_with(
+ self.mapper, sql_util.ColumnAdapter(
+ from_obj, self.mapper._equivalent_columns))
filter_fn = id
@@ -3115,7 +3122,7 @@ class _MapperEntity(_QueryEntity):
def setup_context(self, query, context):
adapter = self._get_entity_clauses(query, context)
- #if self._adapted_selectable is None:
+ # if self._adapted_selectable is None:
context.froms += (self.selectable,)
if context.order_by is False and self.mapper.order_by:
@@ -3124,10 +3131,10 @@ class _MapperEntity(_QueryEntity):
# apply adaptation to the mapper's order_by if needed.
if adapter:
context.order_by = adapter.adapt_list(
- util.to_list(
- context.order_by
- )
- )
+ util.to_list(
+ context.order_by
+ )
+ )
if self._with_polymorphic:
poly_properties = self.mapper._iterate_polymorphic_properties(
@@ -3161,6 +3168,7 @@ class _MapperEntity(_QueryEntity):
def __str__(self):
return str(self.mapper)
+
@inspection._self_inspects
class Bundle(object):
"""A grouping of SQL expressions that are returned by a :class:`.Query`
@@ -3192,7 +3200,8 @@ class Bundle(object):
bn = Bundle("mybundle", MyClass.x, MyClass.y)
- for row in session.query(bn).filter(bn.c.x == 5).filter(bn.c.y == 4):
+ for row in session.query(bn).filter(
+ bn.c.x == 5).filter(bn.c.y == 4):
print(row.mybundle.x, row.mybundle.y)
:param name: name of the bundle.
@@ -3206,7 +3215,7 @@ class Bundle(object):
self.exprs = exprs
self.c = self.columns = ColumnCollection()
self.columns.update((getattr(col, "key", col._label), col)
- for col in exprs)
+ for col in exprs)
self.single_entity = kw.pop('single_entity', self.single_entity)
columns = None
@@ -3225,7 +3234,8 @@ class Bundle(object):
Bundle('b3', MyClass.x, MyClass.y)
)
- q = sess.query(b1).filter(b1.c.b2.c.a == 5).filter(b1.c.b3.c.y == 9)
+ q = sess.query(b1).filter(
+ b1.c.b2.c.a == 5).filter(b1.c.b3.c.y == 9)
.. seealso::
@@ -3266,7 +3276,8 @@ class Bundle(object):
"""
def proc(row, result):
- return util.KeyedTuple([proc(row, None) for proc in procs], labels)
+ return util.KeyedTuple(
+ [proc(row, None) for proc in procs], labels)
return proc
@@ -3318,9 +3329,9 @@ class _BundleEntity(_QueryEntity):
def adapt_to_selectable(self, query, sel):
c = _BundleEntity(query, self.bundle, setup_entities=False)
- #c._label_name = self._label_name
- #c.entity_zero = self.entity_zero
- #c.entities = self.entities
+ # c._label_name = self._label_name
+ # c.entity_zero = self.entity_zero
+ # c.entities = self.entities
for ent in self._entities:
ent.adapt_to_selectable(c, sel)
@@ -3335,14 +3346,15 @@ class _BundleEntity(_QueryEntity):
def row_processor(self, query, context, custom_rows):
procs, labels = zip(
- *[ent.row_processor(query, context, custom_rows)
- for ent in self._entities]
- )
+ *[ent.row_processor(query, context, custom_rows)
+ for ent in self._entities]
+ )
proc = self.bundle.create_row_processor(query, procs, labels)
return proc, self._label_name
+
class _ColumnEntity(_QueryEntity):
"""Column/expression based entity."""
@@ -3354,16 +3366,16 @@ class _ColumnEntity(_QueryEntity):
column = sql.literal_column(column)
self._label_name = column.name
elif isinstance(column, (
- attributes.QueryableAttribute,
- interfaces.PropComparator
- )):
+ attributes.QueryableAttribute,
+ interfaces.PropComparator
+ )):
self._label_name = column.key
column = column._query_clause_element()
else:
self._label_name = getattr(column, 'key', None)
if not isinstance(column, expression.ColumnElement) and \
- hasattr(column, '_select_iterable'):
+ hasattr(column, '_select_iterable'):
for c in column._select_iterable:
if c is column:
break
@@ -3414,7 +3426,7 @@ class _ColumnEntity(_QueryEntity):
for elem in visitors.iterate(column, {})
if 'parententity' in elem._annotations
and actual_froms.intersection(elem._from_objects)
- )
+ )
if self.entities:
self.entity_zero = list(self.entities)[0]
@@ -3456,14 +3468,14 @@ class _ColumnEntity(_QueryEntity):
return entity is self.entity_zero
else:
return not _is_aliased_class(self.entity_zero) and \
- entity.common_parent(self.entity_zero)
+ entity.common_parent(self.entity_zero)
def _resolve_expr_against_query_aliases(self, query, expr, context):
return query._adapt_clause(expr, False, True)
def row_processor(self, query, context, custom_rows):
column = self._resolve_expr_against_query_aliases(
- query, self.column, context)
+ query, self.column, context)
if context.adapter:
column = context.adapter.columns[column]
@@ -3475,7 +3487,7 @@ class _ColumnEntity(_QueryEntity):
def setup_context(self, query, context):
column = self._resolve_expr_against_query_aliases(
- query, self.column, context)
+ query, self.column, context)
context.froms += tuple(self.froms)
context.primary_columns.append(column)
@@ -3493,8 +3505,8 @@ class QueryContext(object):
if query._statement is not None:
if isinstance(query._statement, expression.SelectBase) and \
- not query._statement._textual and \
- not query._statement.use_labels:
+ not query._statement._textual and \
+ not query._statement.use_labels:
self.statement = query._statement.apply_labels()
else:
self.statement = query._statement
@@ -3516,7 +3528,7 @@ class QueryContext(object):
self.eager_joins = {}
self.create_eager_joins = []
self.propagate_options = set(o for o in query._with_options if
- o.propagate_to_loaders)
+ o.propagate_to_loaders)
self.attributes = query._attributes.copy()
@@ -3563,5 +3575,3 @@ class AliasOption(interfaces.MapperOption):
else:
alias = self.alias
query._from_obj_alias = sql_util.ColumnAdapter(alias)
-
-