diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-02-25 19:06:21 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-02-25 19:06:21 -0500 |
| commit | a60ff8f91bf7d995781e6029f9a2a3148e187553 (patch) | |
| tree | 388258614280fe7c4a4efad5c3bb7dcf5ce7c435 | |
| parent | 2bdf5103c804c8d0c033734d4c100172c665a4a3 (diff) | |
| download | sqlalchemy-a60ff8f91bf7d995781e6029f9a2a3148e187553.tar.gz | |
- turn PK getting into idxloader.
- idxloader gets simpler
| -rw-r--r-- | lib/sqlalchemy/orm/base.py | 7 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/loading.py | 9 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/query.py | 32 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 2 |
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 |
