summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-10-25 11:34:37 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-10-26 18:16:02 -0400
commitd6db28556b095dc85fff3e0e09b0e70358a9538b (patch)
treeb74991aeeebcf8ab666816049d3aae17d566abdb /lib/sqlalchemy/ext
parent172d99a8a1282b534aeadafebdd2af0162758931 (diff)
downloadsqlalchemy-d6db28556b095dc85fff3e0e09b0e70358a9538b.tar.gz
Don't cache a query that has before_compile modifications
The :class:`.BakedQuery` will not cache a query that was modified by a :meth:`.QueryEvents.before_compile` event, so that compilation hooks that may be applying ad-hoc modifications to queries will take effect on each run. In particular this is helpful for events that modify queries used in lazy loading as well as eager loading such as "select in" loading. In order to re-enable caching for a query modified by this event, a new flag ``bake_ok`` is added; see :ref:`baked_with_before_compile` for details. A longer term plan to provide a new form of SQL caching should solve this kind of issue more comprehensively. Fixes: #4947 Change-Id: I5823c4fa00e7b6d46a2e8461b02d8b16605a6ed0
Diffstat (limited to 'lib/sqlalchemy/ext')
-rw-r--r--lib/sqlalchemy/ext/baked.py12
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py
index 44e28d045..d18a35a40 100644
--- a/lib/sqlalchemy/ext/baked.py
+++ b/lib/sqlalchemy/ext/baked.py
@@ -225,6 +225,7 @@ class BakedQuery(object):
query = self._as_query(session)
context = query._compile_context()
+
self._bake_subquery_loaders(session, context)
context.session = None
context.query = query = context.query.with_session(None)
@@ -242,7 +243,13 @@ class BakedQuery(object):
"_joinpoint",
):
query.__dict__.pop(attr, None)
- self._bakery[self._effective_key(session)] = context
+
+ # if the query is not safe to cache, we still do everything as though
+ # we did cache it, since the receiver of _bake() assumes subqueryload
+ # context was set up, etc.
+ if context.query._bake_ok:
+ self._bakery[self._effective_key(session)] = context
+
return context
def to_query(self, query_or_session):
@@ -332,6 +339,9 @@ class BakedQuery(object):
like a Query object.
"""
+ if "baked_queries" not in context.attributes:
+ return
+
for k, cache_key, query in context.attributes["baked_queries"]:
bk = BakedQuery(
self._bakery, lambda sess, q=query: q.with_session(sess)