简体   繁体   中英

How to cache SQL Alchemy calls with Flask-Cache and Redis?

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:

  1. What do I put for args and kwargs ? What do these mean? How do I set up a Redis cache with Flask-Cache?

  2. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM