diff --git a/README.md b/README.md index 8f82f86..b9deec0 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,16 @@ being cached, try using a deferred query like: YourModel.query.options(defer('crazy_column')).options(FromCache(cache)).get() ``` +You can also integrate with [baked queries](https://docs.sqlalchemy.org/en/13/orm/extensions/baked.html) like so: +```python +baked_query = bakery(lambda session: session.query(YourModel)) +baked_query += lambda q: q.filter(YourModel.id == bindparam('id')) + +obj = baked_query(YourModel.query.session) \ +.with_post_criteria(lambda q: q.options(FromCache(cache))) \ +.params(id=id).one() +``` + Take a look at [Dogpile Caching example][] to more details about how `CachingQuery` works. Most changes to their were made just to integrate it with Flask, Flask-SQLAlchemy and Flask-Caching instead of Dogpile. diff --git a/flask_sqlalchemy_caching/core.py b/flask_sqlalchemy_caching/core.py index f53a751..02d5654 100644 --- a/flask_sqlalchemy_caching/core.py +++ b/flask_sqlalchemy_caching/core.py @@ -51,6 +51,29 @@ def create_func(): return list(BaseQuery.__iter__(self)) else: return BaseQuery.__iter__(self) + def _execute_and_instances(self, context): + """override _execute_and_instances to pull results from dogpile + if the query is invoked directly from an external context. + This method is necessary in order to maintain compatibility + with the "baked query" system now used by default in some + relationship loader scenarios. Note also the + RelationshipCache._generate_cache_key method which enables + the baked query to be used within lazy loads. + .. versionadded:: 1.2.7 + """ + super_ = super(CachingQuery, self) + + if context.query is not self and hasattr(self, "_cache"): + # special logic called when the Query._execute_and_instances() + # method is called directly from the baked query + return iter( + self.get_value( + createfunc=lambda: list(super_._execute_and_instances(context)) + ) + ) + else: + return super_._execute_and_instances(context) + def _get_cache_plus_key(self): """Return a cache region plus key.""" return self._cache.cache, self._get_key()