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]
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),
@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
_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):
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(
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: