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.
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
.
your redis args would look something like this:
cache = Cache(app, config={ 'CACHE_TYPE': 'redis', 'CACHE_KEY_PREFIX': 'fcache', 'CACHE_REDIS_HOST': 'localhost', 'CACHE_REDIS_PORT': '6379', 'CACHE_REDIS_URL': 'redis://localhost:6379' })
Putting the @cache.memoize over a method that grabs the info from the DB should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With