summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-02-28 14:59:17 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2015-02-28 14:59:17 -0500
commitc2cdd32f8ba09b070386143527fa42c28bf528ee (patch)
tree37899aaa97aa481192fdbaca488475ee5530889f /lib
parent0a32227f3ac17847a46ecd2d40e546e0b4f00989 (diff)
downloadsqlalchemy-c2cdd32f8ba09b070386143527fa42c28bf528ee.tar.gz
- BANG! saves 100K calls on orm2010!! woop
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlalchemy/orm/interfaces.py8
-rw-r--r--lib/sqlalchemy/orm/loading.py24
-rw-r--r--lib/sqlalchemy/orm/query.py16
-rw-r--r--lib/sqlalchemy/orm/strategies.py9
4 files changed, 19 insertions, 38 deletions
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index d0f0758cd..627b7fc79 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -109,7 +109,7 @@ class MapperProperty(_MappedAttribute, InspectionAttr, util.MemoizedSlots):
def setup(
self, context, query_entity, path, mapper,
- adapter, column_collection, **kw):
+ adapter, column_collection, populators, **kw):
"""Called by Query for the purposes of constructing a SQL statement.
Each MapperProperty associated with the target mapper processes the
@@ -492,7 +492,7 @@ class StrategizedProperty(MapperProperty):
def setup(
self, context, query_entity, path, mapper,
- adapter, column_collection, **kw):
+ adapter, column_collection, populators, **kw):
loadopt = self._get_context_loader(context, path)
if loadopt and loadopt.strategy:
@@ -502,7 +502,7 @@ class StrategizedProperty(MapperProperty):
strat.setup_query(
context, query_entity, path, mapper,
- adapter, column_collection, loadopt, **kw)
+ adapter, column_collection, populators, loadopt, **kw)
def create_row_processor(
self, result, context, path, mapper,
@@ -615,7 +615,7 @@ class LoaderStrategy(object):
def setup_query(
self, context, query_entity, path, mapper,
- adapter, column_collection, loadopt, **kw):
+ adapter, column_collection, populators, loadopt, **kw):
"""Establish column and other state for a given QueryContext.
This method fulfills the contract specified by MapperProperty.setup().
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index 4b1f6f6f5..c4099a743 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -46,10 +46,6 @@ def instances(query, cursor, context):
for query_entity in query._entities:
query_entity.setup_context(query, context, cursor)
- for vals in context.todo:
- fn, args = vals[0], vals[1:]
- fn(cursor, *args)
-
try:
(labels, process) = list(zip(*context.loaders))
@@ -233,6 +229,8 @@ def _instance_processor(
load_is_polymorphic = mapper.polymorphic_on is not None
+ populators = collections.defaultdict(list)
+
if result is None:
for prop in props_toload:
@@ -243,6 +241,7 @@ def _instance_processor(
mapper,
adapter,
column_collection,
+ populators,
only_load_props=only_load_props,
)
@@ -253,20 +252,11 @@ def _instance_processor(
identity_class = mapper._identity_class
- populators = collections.defaultdict(list)
- props = mapper._props.values()
- if only_load_props is not None:
- props = (p for p in props if p.key in only_load_props)
+ if result is not None:
+ props = mapper._props.values()
+ if only_load_props is not None:
+ props = (p for p in props if p.key in only_load_props)
- if result is None:
- for prop in props:
- context.todo.append(
- (
- prop.create_row_processor, context, path,
- mapper, adapter, populators
- )
- )
- else:
for prop in props:
prop.create_row_processor(
result, context, path, mapper, adapter, populators)
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 1128bc91c..8988cac1b 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -3641,13 +3641,7 @@ class _ColumnEntity(_QueryEntity):
context.froms += tuple(self.froms)
context.primary_columns.append(column)
- context.todo.append(
- (self.create_row_processor, context, column, loaders)
- )
-
- def create_row_processor(self, result, context, column, loaders):
- getter = result._getter(column)
-
+ getter = operator.itemgetter(column)
if loaders is not None:
loaders.append((self._label_name, getter))
else:
@@ -3695,14 +3689,6 @@ class QueryContext(object):
o.propagate_to_loaders)
self.attributes = query._attributes.copy()
self.loaders = []
- self.todo = []
-
- def _getter(self, column, result):
-
- if self.outer_adapter:
- column = self.outer_adapter.columns[column]
-
- return result._getter(column)
class AliasOption(interfaces.MapperOption):
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index cbdbaa200..95ed198a5 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -23,6 +23,8 @@ from .interfaces import (
LoaderStrategy, StrategizedProperty
)
from .session import _state_session
+
+import operator
import itertools
@@ -134,7 +136,7 @@ class ColumnLoader(LoaderStrategy):
def setup_query(
self, context, query_entity, path, mapper,
- adapter, column_collection, loadopt, **kw):
+ adapter, column_collection, populators, loadopt, **kw):
for c in self.columns:
if adapter:
c = adapter.columns[c]
@@ -146,6 +148,9 @@ class ColumnLoader(LoaderStrategy):
# the column on the base table. More specific logic
# should be added here so that we need not bother
# querying out every column.
+ populators["quick"].append(
+ (self.key, operator.itemgetter(self.columns[0]))
+ )
def create_row_processor(
self, result, context, path,
@@ -156,7 +161,7 @@ class ColumnLoader(LoaderStrategy):
for col in self.columns:
if adapter:
col = adapter.columns[col]
- getter = context._getter(col, result)
+ getter = result._getter(col)
if getter:
populators["quick"].append((self.key, getter))
break