2016-06-03 3 views
2

Я кэширую некоторые результаты вычислений в приложении Django с использованием кэша базы данных Django (https://docs.djangoproject.com/en/1.8/topics/cache/#database-caching).Перечисление ключей в кеше базы данных Django

Каким образом можно перечислять все ключи, хранящиеся в кеше в данный момент. Иногда мне нужно аннулировать (удалять) части кеша до истечения срока действия (потому что я отлаживаю). Ключи кеша генерируются сложным вычислением, и я не хочу повторять это вычисление. Я знаю префикс ключей кеша, которые хотел бы удалить, но я не знаю полных ключевых строк.

Я не вижу сразу в API кеша, как я мог это сделать. Я могу получить записи, создавать ключи, удалять записи и очищать весь кеш: https://docs.djangoproject.com/en/1.8/topics/cache/#the-low-level-cache-api

Сейчас я должен извлечь ключи с помощью операторов SQL, которые являются PITA. Я хотел бы написать команду управления, которую я могу использовать для отмены недействительных разделов.


Пример:

settings.py:

CACHES = { 
    'default': { 
     'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 
     'LOCATION': 'default-cache', 
    }, 
    'staticfiles': { 
     'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 
     'LOCATION': 'static-files', 
    }, 
    'bla_stats': { 
     'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 
     'LOCATION': 'django_bla_stats_cache', 
    } 
} 

Я создал кэш, как описано в документации Django я связан. Размещение некоторых данных в кеше (без истечения: я управляю записями).

from django.core.cache import caches 

cache = caches['bla_stats'] 
cache.set("a_d3e6a1e1-0565-4d20-8887-4fda47186299", "foo", None) 
cache.set("a_e79a1e0d-bfe1-4a04-8db3-42495c09e780", "bar", None) 
cache.set("b_390d42ec-2b70-436d-8600-404034b07fe9", "fiz", None) 
cache.set("b_a2d3cb52-8941-4812-8186-676ee3de0ec3", "baz", None) 

И вот вопрос: как я могу найти все ключи в кэш, который имеет ключевое префикс «B_» в любой данный момент времени?

+1

Это должно быть возможно. Если вы добавите свой существующий код в вопрос, будет легче понять, что именно вы хотите достичь, и предложить альтернативные способы. –

+0

Хорошо, я добавил несколько примеров. –

ответ

1

Предполагая, что вы используете MySQL в качестве базы данных БД, этот подкласс класса DatabaseCache должен работать, чтобы вернуть словарь всех результатов запроса типа LIKE в кеш-ключи.

class DatabaseCacheExtended(DatabaseCache): 
    def get_where(self, query, default=None, version=None): 
     db = router.db_for_read(self.cache_model_class) 
     table = connections[db].ops.quote_name(self._table) 

     with connections[db].cursor() as cursor: 
      cursor.execute("SELECT cache_key, value, expires FROM %s " 
          "WHERE cache_key LIKE %%s" % table, [query]) 
      rows = cursor.fetchall() 
     if len(rows) < 1: 
      return {} 
     return_d ={} 
     for row in rows: 
      value = connections[db].ops.process_clob(row[1]) 
      return_d[row[0]] = pickle.loads(base64.b64decode(force_bytes(value))) 
     return return_d 

Тогда вам просто нужно изменить зарегистрированный бэкенд в вашем settings.py

'bla_stats': { 
     'BACKEND': 'path.to.DatabaseCacheExtended', 
     'LOCATION': 'django_bla_stats_cache', 
    } 

Пример:

>>> from django.core.cache import caches 
>>> cache = caches['bla_stats'] 
>>> cache.get_where("b_%") 
... {"b_key1":"val1", "b_key2":"val2"} 
1

API кеша Django не предлагает то, что вы ищете, поэтому ни одна из реализаций не будет. Одним из решений было бы создание собственного бэкэнда.

Вам все равно придется гадать вокруг SQL-запросов, но вы можете подклассифицировать DatabaseCache, чтобы создать собственный собственный бэкэнд. Добавьте метод, который позволяет запрашивать ключи по префиксу или удалять с помощью префикса, а затем переносить их в команду управления для легкого доступа.

Смежные вопросы