【问题标题】:How to cache SQL Alchemy calls with Flask-Cache and Redis?如何使用 Flask-Cache 和 Redis 缓存 SQL Alchemy 调用?
【发布时间】:2014-08-26 16:02:15
【问题描述】:

我有一个 Flask 应用程序,它从 Web 表单中获取参数,使用 SQL Alchemy 查询数据库并返回 Jinja 生成的 HTML,显示一个带有结果的表格。我想缓存对数据库的调用。我查看了 Redis (Using redis as an LRU cache for postgres),然后找到了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. 一旦设置了缓存,我似乎想以某种方式“memoize”调用数据库,这样如果方法获得相同的查询,它就会缓存输出。我该怎么做呢?我最好的猜测是将调用 SQL Alchemy 包装在一个方法中,然后可以给定 memoize 装饰器?这样,如果将两个相同的查询传递给该方法,Flask-Cache 将识别这一点并返回到适当的响应。我猜它会是这样的:

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

这似乎是 Redis + Flask + Flask-Cache + SQL Alchemy 的一个相当普遍的用法,但我无法找到一个完整的示例来遵循。如果有人可以发布一个,那将非常有帮助 - 但对我和其他人来说。

【问题讨论】:

  • 我遇到的问题是,将查询对象作为参数传递会使用对象的内存地址产生 memoize。一个包装类解决了这个问题。希望这可能对某人有所帮助..

标签: python flask redis sqlalchemy flask-cache


【解决方案1】:

您不需要创建自定义RedisCache 类。该文档只是在教您如何创建 flask-cache 中不可用的新后端。但是RedisCache 已经在werkzeug >= 0.7 中可用,你可能已经安装了它,因为它是flask 的核心依赖项之一。

这就是我可以使用 redis 后端运行烧瓶缓存的方式:

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

【讨论】:

  • pip install redis 在我的情况下 :) 请记住,您需要像 Riz 在他的回答中描述的那样配置 redis 连接。
  • 注意:使用from flask flaskt.ext.cache import Cache 导入烧瓶扩展已被弃用:改为使用from flask_cache import Cache
【解决方案2】:

你的 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 放在从数据库中获取信息的方法上应该可以工作。

【讨论】:

  • 如果我按照这个例子,我得到“ImportError: redis is not a valid FlaskCache backend”
  • 如果我将 CACHE_TYPE 更改为 'redis' 我会得到 ERROR:flask_cache:Exception possible due to cache backend....AttributeError: 'Flask' object has no attribute 'mget'
  • 确保你已经安装了 redid python 库。 pip install redis
  • 如何设置 Redis 主机用于生产(不使用 localhost 作为主机)?我正在尝试寻找一个好的在线指南来设置 Redis 主机,但找不到任何东西。
猜你喜欢
  • 2014-01-20
  • 2014-03-22
  • 2015-10-10
  • 1970-01-01
  • 2017-07-06
  • 2016-01-06
  • 2014-09-09
  • 2020-03-20
相关资源
最近更新 更多