summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/query.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-03-11 20:22:42 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2015-03-11 20:31:11 -0400
commite3b46bd62405b6ff57119e164718118f3e3565e0 (patch)
tree0f742a7c4a59490778b198396c66066bc2beb122 /lib/sqlalchemy/orm/query.py
parentb815e9483319b93f98bef11c7d47378441f78d21 (diff)
downloadsqlalchemy-e3b46bd62405b6ff57119e164718118f3e3565e0.tar.gz
- Added a new extension suite :mod:`sqlalchemy.ext.baked`. This
simple but unusual system allows for a dramatic savings in Python overhead for the construction and processing of orm :class:`.Query` objects, from query construction up through rendering of a string SQL statement. fixes #3054
Diffstat (limited to 'lib/sqlalchemy/orm/query.py')
-rw-r--r--lib/sqlalchemy/orm/query.py87
1 files changed, 57 insertions, 30 deletions
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index c6fdf479e..05349cf0b 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -26,7 +26,7 @@ from . import (
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, InspectionAttr
from .path_registry import PathRegistry
from .util import (
AliasedClass, ORMAdapter, join as orm_join, with_parent, aliased
@@ -831,7 +831,9 @@ class Query(object):
:return: The object instance, or ``None``.
"""
+ return self._get_impl(ident, loading.load_on_ident)
+ def _get_impl(self, ident, fallback_fn):
# convert composite types to individual args
if hasattr(ident, '__composite_values__'):
ident = ident.__composite_values__()
@@ -862,7 +864,7 @@ class Query(object):
return None
return instance
- return loading.load_on_ident(self, key)
+ return fallback_fn(self, key)
@_generative()
def correlate(self, *args):
@@ -3332,7 +3334,7 @@ class _MapperEntity(_QueryEntity):
@inspection._self_inspects
-class Bundle(object):
+class Bundle(InspectionAttr):
"""A grouping of SQL expressions that are returned by a :class:`.Query`
under one namespace.
@@ -3528,14 +3530,20 @@ class _ColumnEntity(_QueryEntity):
def __init__(self, query, column, namespace=None):
self.expr = column
self.namespace = namespace
+ search_entities = True
if isinstance(column, util.string_types):
column = sql.literal_column(column)
self._label_name = column.name
+ search_entities = False
+ _entity = None
elif isinstance(column, (
attributes.QueryableAttribute,
interfaces.PropComparator
)):
+ _entity = column._parententity
+ if _entity is not None:
+ search_entities = False
self._label_name = column.key
column = column._query_clause_element()
if isinstance(column, Bundle):
@@ -3558,6 +3566,7 @@ class _ColumnEntity(_QueryEntity):
)
else:
self._label_name = getattr(column, 'key', None)
+ search_entities = True
self.type = type_ = column.type
if type_.hashable:
@@ -3588,30 +3597,38 @@ class _ColumnEntity(_QueryEntity):
# leaking out their entities into the main select construct
self.actual_froms = actual_froms = set(column._from_objects)
- all_elements = [
- elem for elem in visitors.iterate(column, {})
- if 'parententity' in elem._annotations
- ]
-
- self.entities = util.unique_list([
- elem._annotations['parententity']
- for elem in all_elements
- if 'parententity' in elem._annotations
- ])
-
- self._from_entities = set([
- elem._annotations['parententity']
- for elem in all_elements
- if 'parententity' in elem._annotations
- and actual_froms.intersection(elem._from_objects)
- ])
-
- if self.entities:
- self.entity_zero = self.entities[0]
- elif self.namespace is not None:
- self.entity_zero = self.namespace
+ if not search_entities:
+ self.entity_zero = _entity
+ if _entity:
+ self.entities = [_entity]
+ else:
+ self.entities = []
+ self._from_entities = set(self.entities)
else:
- self.entity_zero = None
+ all_elements = [
+ elem for elem in visitors.iterate(column, {})
+ if 'parententity' in elem._annotations
+ ]
+
+ self.entities = util.unique_list([
+ elem._annotations['parententity']
+ for elem in all_elements
+ if 'parententity' in elem._annotations
+ ])
+
+ self._from_entities = set([
+ elem._annotations['parententity']
+ for elem in all_elements
+ if 'parententity' in elem._annotations
+ and actual_froms.intersection(elem._from_objects)
+ ])
+
+ if self.entities:
+ self.entity_zero = self.entities[0]
+ elif self.namespace is not None:
+ self.entity_zero = self.namespace
+ else:
+ self.entity_zero = None
supports_single_entity = False
@@ -3673,10 +3690,15 @@ class _ColumnEntity(_QueryEntity):
class QueryContext(object):
- multi_row_eager_loaders = False
- adapter = None
- froms = ()
- for_update = None
+ __slots__ = (
+ 'multi_row_eager_loaders', 'adapter', 'froms', 'for_update',
+ 'query', 'session', 'autoflush', 'populate_existing',
+ 'invoke_all_eagers', 'version_check', 'refresh_state',
+ 'primary_columns', 'secondary_columns', 'eager_order_by',
+ 'eager_joins', 'create_eager_joins', 'propagate_options',
+ 'attributes', 'statement', 'from_clause', 'whereclause',
+ 'order_by', 'labels', '_for_update_arg', 'runid', 'partials'
+ )
def __init__(self, query):
@@ -3693,8 +3715,13 @@ class QueryContext(object):
self.whereclause = query._criterion
self.order_by = query._order_by
+ self.multi_row_eager_loaders = False
+ self.adapter = None
+ self.froms = ()
+ self.for_update = None
self.query = query
self.session = query.session
+ self.autoflush = query._autoflush
self.populate_existing = query._populate_existing
self.invoke_all_eagers = query._invoke_all_eagers
self.version_check = query._version_check