Как кэшировать вызовы SQL Alchemy с помощью Flask-Cache и Redis?

У меня есть приложение Flask, которое получает параметры из веб-формы, запрашивает базу данных с помощью SQL Alchemy и возвращает сгенерированный Jinja HTML-код, показывающий таблицу с результатами. Я хочу кешировать звонки в БД. Я посмотрел на Redis (используя redis как LRU-кеш для 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. Что я положу для args и kwargs? Что это значит? Как настроить кэш Redis с помощью Flask-Cache?

  2. После настройки кэша кажется, что я бы хотел как-то " запоминать " вызовы БД, чтобы, если метод получал тот же запрос, он кэшировал выходные данные. Как мне это сделать? Моим лучшим предположением было бы заключить вызов SQL Alchemy в метод, который затем можно было бы передать декоратору memoize? Таким образом, если в метод передаются два идентичных запроса, Flask-Cache распознает это и вернется к соответствующему ответу. Я предполагаю, что это будет выглядеть так:

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

Это похоже на довольно распространенное использование Redis + Flask + Flask-Cache + SQL Alchemy, но я не могу найти полный пример для подражания. Если бы кто-то мог опубликовать один, это было бы очень полезно - но для меня и для других в будущем.

Ответы

Ответ 1

Вам не нужно создавать пользовательский класс RedisCache. Документы просто учат, как создавать новые бэкэнды, которые недоступны в flask-cache. Но RedisCache уже доступен в werkzeug >= 0.7, который вы, возможно, уже установили, потому что это одна из основных зависимостей фляги.

Вот как я могу запустить кэш-флешку с бэкэндом 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.

Ответ 2

ваши redis args выглядят примерно так:

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 над методом, который захватывает информацию из БД, должно работать.