From: Mike Bayer Date: Wed, 17 May 2017 02:13:40 +0000 (-0400) Subject: - give SelectinLoader its own bakery, dont use mapper X-Git-Tag: rel_1_2_0b1~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2869b86ea44225d17602e54f663055290a86d4f4;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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 --- diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py index 249f5db4e9..95b618f3f5 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 05bb55d58d..dc69ae99db 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: