]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- give SelectinLoader its own bakery, dont use mapper
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 17 May 2017 02:13:40 +0000 (22:13 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 17 May 2017 02:13:40 +0000 (22:13 -0400)
level cache
- include SelectinLoader itself in the cache key, though
this is currently not critical

Change-Id: I8e4bcd579277fbe53d9c7eca3552a0b8ab9d7a39

lib/sqlalchemy/ext/baked.py
lib/sqlalchemy/orm/strategies.py

index 249f5db4e915172e6e4807902533fc495ca4e020..95b618f3f5dd0b6a9cb7e445bc74bf1dbc64d162 100644 (file)
@@ -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),
index 05bb55d58d4e5997b0f2b551334b3a2c4ee042f4..dc69ae99db8e28fcf6019848c31d588f385b8144 100644 (file)
@@ -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: