summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-02-25 19:06:21 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2015-02-25 19:06:21 -0500
commita60ff8f91bf7d995781e6029f9a2a3148e187553 (patch)
tree388258614280fe7c4a4efad5c3bb7dcf5ce7c435
parent2bdf5103c804c8d0c033734d4c100172c665a4a3 (diff)
downloadsqlalchemy-a60ff8f91bf7d995781e6029f9a2a3148e187553.tar.gz
- turn PK getting into idxloader.
- idxloader gets simpler
-rw-r--r--lib/sqlalchemy/orm/base.py7
-rw-r--r--lib/sqlalchemy/orm/loading.py9
-rw-r--r--lib/sqlalchemy/orm/query.py32
-rw-r--r--lib/sqlalchemy/orm/strategies.py2
4 files changed, 29 insertions, 21 deletions
diff --git a/lib/sqlalchemy/orm/base.py b/lib/sqlalchemy/orm/base.py
index 7bfafdc2b..7330caa3d 100644
--- a/lib/sqlalchemy/orm/base.py
+++ b/lib/sqlalchemy/orm/base.py
@@ -351,6 +351,13 @@ def _is_aliased_class(entity):
getattr(insp, "is_aliased_class", False)
+class _IdxLoader(object):
+ __slots__ = ('__call__',)
+
+ def setup(self, index):
+ self.__call__ = operator.itemgetter(index)
+
+
def _entity_descriptor(entity, key):
"""Return a class attribute given an entity and string name.
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index 818b11b35..b3ccefd5f 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -16,6 +16,7 @@ from __future__ import absolute_import
from .. import util
from . import attributes, exc as orm_exc
+from .base import _IdxLoader
from ..sql import util as sql_util
from .util import _none_set, state_str
from .. import exc as sa_exc
@@ -248,6 +249,12 @@ def instance_processor(mapper, props_toload, context, column_collection,
if adapter:
pk_cols = [adapter.columns[c] for c in pk_cols]
+ pk_getters = [_IdxLoader()] * len(pk_cols)
+ context.column_processors.extend(
+ (pk_col, pk_getter.setup)
+ for pk_col, pk_getter in zip(pk_cols, pk_getters)
+ )
+
identity_class = mapper._identity_class
props = mapper._props.values()
@@ -301,7 +308,7 @@ def instance_processor(mapper, props_toload, context, column_collection,
# session, or we have to create a new one
identitykey = (
identity_class,
- tuple([row[column] for column in pk_cols])
+ tuple(getter(row) for getter in pk_getters)
)
instance = session_identity_map.get(identitykey)
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 97378dbfc..53cf227ee 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -20,14 +20,13 @@ database to return iterable result sets.
"""
from itertools import chain
-import operator
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, _IdxLoader
from .path_registry import PathRegistry
from .util import (
AliasedClass, ORMAdapter, join as orm_join, with_parent, aliased
@@ -3092,9 +3091,11 @@ class Query(object):
# initiate indexes for column processor functions
# that have been established
- for idx, col in enumerate(
- context.primary_columns + context.secondary_columns):
- context.column_processors[col](idx)
+ context._setup_column_processors(
+ enumerate(
+ context.primary_columns + context.secondary_columns
+ )
+ )
return statement
@@ -3672,7 +3673,7 @@ class _ColumnEntity(_QueryEntity):
context.primary_columns.append(column)
loader = _IdxLoader()
- context.column_processors[column] = loader.setup
+ context.column_processors.append((column, loader.setup))
if loaders is not None:
loaders.append((self._label_name, loader))
@@ -3683,16 +3684,6 @@ class _ColumnEntity(_QueryEntity):
return str(self.column)
-class _IdxLoader(object):
- __slots__ = ('getter',)
-
- def setup(self, index):
- self.getter = operator.itemgetter(index)
-
- def __call__(self, row):
- return self.getter(row)
-
-
class QueryContext(object):
multi_row_eager_loaders = False
adapter = None
@@ -3723,7 +3714,7 @@ class QueryContext(object):
self.refresh_state = query._refresh_state
self.primary_columns = []
self.secondary_columns = []
- self.column_processors = {}
+ self.column_processors = []
self.eager_order_by = []
self.eager_joins = {}
self.create_eager_joins = []
@@ -3733,8 +3724,11 @@ class QueryContext(object):
self.loaders = []
def _setup_column_processors(self, cols):
- for idx, col in cols:
- self.column_processors[col](idx)
+ d = dict(
+ (col, idx) for idx, col in cols
+ )
+ for col, fn in self.column_processors:
+ fn(d[col])
class AliasOption(interfaces.MapperOption):
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 0723a33e8..085faaa2d 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -151,7 +151,7 @@ class ColumnLoader(LoaderStrategy):
populators["quick"].append(
(self.key, operator.itemgetter(index))
)
- context.column_processors[self.columns[0]] = quick_populate
+ context.column_processors.append((self.columns[0], quick_populate))
def init_class_attribute(self, mapper):
self.is_class_level = True