web-dev-qa-db-fra.com

Comment mettre en cache les appels SQL Alchemy avec Flask-Cache et Redis?

J'ai une application Flask qui prend les paramètres d'un formulaire Web, interroge une base de données avec SQL Alchemy et retourne du code HTML généré par Jinja montrant une table avec les résultats. Je veux mettre en cache les appels vers la base de données . J'ai regardé dans Redis ( tiliser redis comme cache LRU pour postgres ), ce qui m'a conduit à http://pythonhosted.org/Flask-Cache/ .

Maintenant, j'essaie d'utiliser Redis + Flask-Cache pour mettre en cache les appels vers la base de données. Sur la base des documents Flask-Cache, il semble que je doive configurer un cache Redis personnalisé.

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)

De là, j'aurais besoin de quelque chose comme:

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

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

J'ai deux questions:

  1. Que dois-je mettre pour args et kwargs? Qu'est-ce que cela signifie? Comment configurer un cache Redis avec Flask-Cache?

  2. Une fois le cache configuré, il semble que je voudrais en quelque sorte " mémoriser " appeler la base de données de sorte que si la méthode obtient la même requête, la sortie soit mise en cache. Comment puis-je faire cela? Ma meilleure supposition serait d'envelopper l'appel de l'alchimie SQL dans une méthode qui pourrait ensuite être donnée à un décorateur de mémos? De cette façon, si deux requêtes identiques étaient transmises à la méthode, Flask-Cache reconnaîtrait cela et retournerait à la réponse appropriée. Je suppose que cela ressemblerait à ceci:

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

Cela semble être une utilisation assez courante de Redis + Flask + Flask-Cache + SQL Alchemy, mais je ne trouve pas d'exemple complet à suivre. Si quelqu'un pouvait en poster un, ce serait super utile - mais pour moi et pour les autres sur toute la ligne.

24
bernie2436

Vous n'avez pas besoin de créer une classe RedisCache personnalisée. La documentation explique simplement comment créer de nouveaux backends qui ne sont pas disponibles dans flask-cache. Mais RedisCache est déjà disponible dans werkzeug >= 0.7, que vous avez peut-être déjà installé car il s'agit de l'une des principales dépendances de flask.

Voici comment je pourrais exécuter le flask-cache avec 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)

La raison pour laquelle vous obtenez "ImportError: redis is not a valid FlaskCache backend" est probablement parce que vous n'avez pas installé redis (bibliothèque python) que vous pouvez simplement installer en:
pip install redis.

42
suzanshakya

vos arguments redis ressembleraient à ceci:

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

Mettre le @ cache.memoize sur une méthode qui récupère les informations de la base de données devrait fonctionner.

14
Riz