How to cache SQL Alchemy calls with Flask-Cache and Redis?
flask, flask-cache, python, redis, sqlalchemy
Solution
You don't need to create custom `RedisCache` class. The docs is just teaching how you would create new backends that are not available in `flask-cache`. But `RedisCache` is already available in `werkzeug >= 0.7`, which you might have already installed because it is one of the core dependencies of flask.
This is how I could run the flask-cache with redis backend:
import time
from flask import Flask
from flask_cache import Cache
app = Flask(__name__)
cache = Cache(app, config={'CACHE_TYPE': 'redis'})
@cache.memoize(timeout=60)
def query_db():
time.sleep(5)
return "Results from DB"
@app.route('/')
def index():
return query_db()
app.run(debug=True)
The reason you're getting `"ImportError: redis is not a valid FlaskCache backend"` is probably because you don't have `redis` (python library) installed which you can simply install by: `pip install redis`.
Problem
I have a Flask app that takes parameters from a web form, queries a DB with SQL Alchemy and returns Jinja-generated HTML showing a table with the results. I want to cache the calls to the DB. I looked into Redis (Using redis as an LRU cache for postgres), which led me to http://pythonhosted.org/Flask-Cache/. Now I am trying to use Redis + Flask-Cache to cache the calls to the DB. Based on the Flask-Cache docs, it seems like I need to set up a custom Redis cache. ``` class RedisCache(BaseCache): def __init__(self, servers, default_timeout=500): pass def redis(app, config, args, kwargs): args.append(app.config['REDIS_SERVERS']) return RedisCache(*args, **kwargs) ``` From there I would need to something like: ``` # not sure what to put for args or kwargs cache = redis(app, config={'CACHE_TYPE': 'redis'}) app = Flask(__name__) cache.init_app(app) ``` I have two questions: What do I put for `args` and `kwargs`? What do these mean? How do I set up a Redis cache with Flask-Cache? Once the cache is set up, it seems like I would want to somehow "memoize" the calls the DB so that if the method gets the same query it has the output cached. How do I do this? My best guess would be to wrap the call the SQL Alchemy in a method that could then be given memoize decorator? That way if two identical queries were passed to the method, Flask-Cache would recognize this and return to the appropriate response. I'm guessing that it would look like this: ``` @cache.memoize(timeout=50) def queryDB(q): return q.all() ``` This seems like a fairly common use of Redis + Flask + Flask-Cache + SQL Alchemy, but I am unable to find a complete example to follow. If someone could post one, that would be super helpful -- but for me and for others down the line.