Как использовать колбу-кэш с флягой-restful

Как использовать Flask-Cache @cache.cached() decorator с Flask-Restful? Например, у меня есть класс Foo, унаследованный от Resource, а Foo имеет методы get, post, put и delete.

Как я могу аннулировать результаты кэширования после POST?

@api.resource('/whatever')
class Foo(Resource):
    @cache.cached(timeout=10)
    def get(self):
        return expensive_db_operation()

    def post(self):
        update_db_here()

        ## How do I invalidate the value cached in get()?
        return something_useful()

Ответы

Ответ 3

Поскольку Flask-Cache реализация не дает вам доступ к базовому объекту cache, вам нужно явно создать экземпляр клиента Redis и использовать его keys метод (список всех ключей кеша).

  • Метод cache_key используется для переопределения генерации ключа по умолчанию в вашем декораторе cache.cached.
  • Метод clear_cache очистит только часть кеша, соответствующую текущему ресурсу.

Это решение, которое было протестировано только для Redis, и реализация, вероятно, будет немного отличаться при использовании другого механизма кэширования.

from app import cache # The Flask-Cache object
from config import CACHE_REDIS_HOST, CACHE_REDIS_PORT # The Flask-Cache config
from redis import Redis
from flask import request
import urllib

redis_client = Redis(CACHE_REDIS_HOST, CACHE_REDIS_PORT)

def cache_key():
   args = request.args
   key = request.path + '?' + urllib.urlencode([
     (k, v) for k in sorted(args) for v in sorted(args.getlist(k))
   ])
   return key

@api.resource('/whatever')
class Foo(Resource):

    @cache.cached(timeout=10, key_prefix=cache_key)
    def get(self):
        return expensive_db_operation()

    def post(self):
        update_db_here()
        self.clear_cache()
        return something_useful()

    def clear_cache(self):
        # Note: we have to use the Redis client to delete key by prefix,
        # so we can't use the 'cache' Flask extension for this one.
        key_prefix = request.path
        keys = [key for key in redis_client.keys() if key.startswith(key_prefix)]
        nkeys = len(keys)
        for key in keys:
            redis_client.delete(key)
        if nkeys > 0:
            log.info("Cleared %s cache keys" % nkeys)
            log.info(keys)