Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
23 changes: 23 additions & 0 deletions flask_sqlalchemy_caching/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down