如何使用Flask-Cache和Redis缓存SQL Alchemy调用?

28 投票
2 回答
26962 浏览
提问于 2025-04-18 12:13

我有一个Flask应用,它从网页表单获取参数,然后用SQL Alchemy查询数据库,最后返回用Jinja生成的HTML,显示一个结果表格。我想要缓存对数据库的调用。我查了一下Redis(使用Redis作为Postgres的LRU缓存),然后找到了http://pythonhosted.org/Flask-Cache/

现在我想用Redis和Flask-Cache来缓存对数据库的调用。根据Flask-Cache的文档,似乎我需要设置一个自定义的Redis缓存。

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)

接下来我需要做一些类似这样的事情:

# not sure what to put for args or kwargs
cache = redis(app, config={'CACHE_TYPE': 'redis'})

app = Flask(__name__)
cache.init_app(app)

我有两个问题:

  1. 我应该在argskwargs里放什么?这两个是什么意思?我该如何用Flask-Cache设置Redis缓存?

  2. 一旦缓存设置好了,我想要以某种方式“记忆化”对数据库的调用,这样如果方法接收到相同的查询,它就能返回缓存的结果。我该怎么做?我猜想可以把SQL Alchemy的调用包裹在一个方法里,然后给这个方法加上记忆化的装饰器?这样如果两个相同的查询被传递给这个方法,Flask-Cache就能识别并返回相应的结果。我想它会像这样:

    @cache.memoize(timeout=50)
    def queryDB(q):
        return q.all()
    

这看起来是Redis + Flask + Flask-Cache + SQL Alchemy的一个比较常见的用法,但我找不到完整的示例来参考。如果有人能发一个,那就太有帮助了——对我和其他人来说都是。

2 个回答

18

你的 Redis 参数大概是这样的:

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'
    })

在一个从数据库获取信息的方法上加上 @cache.memoize 这个装饰器应该可以正常工作。

51

你不需要自己创建一个特别的 RedisCache 类。文档只是教你如何创建一些在 flask-cache 中没有的后端。但其实 RedisCachewerkzeug >= 0.7 中已经可以用了,你可能已经安装过这个,因为它是 flask 的核心依赖之一。

这是我如何用 redis 后端运行 flask-cache 的方法:

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)

你看到 "ImportError: redis is not a valid FlaskCache backend" 这个错误,可能是因为你没有安装 redis(一个 Python 库)。你可以通过以下命令简单安装它:
pip install redis

撰写回答