summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-05-16 22:13:40 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2017-05-16 22:13:40 -0400
commit2869b86ea44225d17602e54f663055290a86d4f4 (patch)
treeca025ad81430ae7bdd6d2f538ed71b78c6f9e0e0
parent75c8b88cddeeadb539fce1c038997d0aebe6f621 (diff)
downloadsqlalchemy-2869b86ea44225d17602e54f663055290a86d4f4.tar.gz
- give SelectinLoader its own bakery, dont use mapper
level cache - include SelectinLoader itself in the cache key, though this is currently not critical Change-Id: I8e4bcd579277fbe53d9c7eca3552a0b8ab9d7a39
-rw-r--r--lib/sqlalchemy/ext/baked.py3
-rw-r--r--lib/sqlalchemy/orm/strategies.py30
2 files changed, 24 insertions, 9 deletions
diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py
index 249f5db4e..95b618f3f 100644
--- a/lib/sqlalchemy/ext/baked.py
+++ b/lib/sqlalchemy/ext/baked.py
@@ -127,7 +127,7 @@ class BakedQuery(object):
invocation.
"""
- if not full:
+ if not full and not self._spoiled:
_spoil_point = self._clone()
_spoil_point._cache_key += ('_query_only', )
self.steps = [_spoil_point._retrieve_baked_query]
@@ -157,6 +157,7 @@ class BakedQuery(object):
self.spoil()
elif cache_key is not None:
key += cache_key
+
self.add_criteria(
lambda q: q._with_current_path(effective_path).
_conditional_options(*options),
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 05bb55d58..dc69ae99d 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -1749,10 +1749,10 @@ class JoinedLoader(AbstractRelationshipLoader):
@log.class_logger
@properties.RelationshipProperty.strategy_for(lazy="selectin")
-class SelectInLoader(AbstractRelationshipLoader):
+class SelectInLoader(AbstractRelationshipLoader, util.MemoizedSlots):
__slots__ = (
'join_depth', '_parent_alias', '_in_expr', '_parent_pk_cols',
- '_zero_idx'
+ '_zero_idx', '_bakery'
)
_chunksize = 500
@@ -1776,6 +1776,21 @@ class SelectInLoader(AbstractRelationshipLoader):
_get_strategy((("lazy", "select"),)).\
init_class_attribute(mapper)
+ @util.dependencies("sqlalchemy.ext.baked")
+ def _memoized_attr__bakery(self, baked):
+ return baked.bakery(size=50, _size_alert=self._alert_lru_cache_limit)
+
+ def _alert_lru_cache_limit(self, lru_cache):
+ util.warn(
+ "Compiled statement cache for selectin loader on attribute %s is "
+ "reaching its size threshold of %d. Consider setting "
+ "bake_queries=False for this relationship. Please refer to "
+ "http://docs.sqlalchemy.org/en/latest/faq/performance.html"
+ "#faq_compiled_cache_threshold"
+ " for best practices." %
+ (self.parent_property,
+ lru_cache.size_threshold))
+
def create_row_processor(
self, context, path, loadopt, mapper,
result, adapter, populators):
@@ -1832,12 +1847,10 @@ class SelectInLoader(AbstractRelationshipLoader):
pk_cols = self._parent_pk_cols
pa = self._parent_alias
- q = baked.BakedQuery(
- # TODO: use strategy-local cache
- self.mapper._compiled_cache,
+ q = self._bakery(
lambda session: session.query(
- query.Bundle("pk", *pk_cols), effective_entity
- )
+ query.Bundle("pk", *pk_cols), effective_entity,
+ ), self
)
q.add_criteria(
@@ -1853,7 +1866,8 @@ class SelectInLoader(AbstractRelationshipLoader):
orig_query = context.query
q._add_lazyload_options(
- orig_query._with_options, path[self.parent_property]
+ orig_query._with_options,
+ path[self.parent_property]
)
if orig_query._populate_existing: