枚举 Django 数据库缓存中的键
Enumerating keys in Django Database Cache
我正在使用 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_" 的所有键?
Django 的缓存 API 不提供您正在寻找的内容,因此 none 的实现也可以。一种解决方案是创建自己的后端。
您仍然需要处理一些 SQL 查询,但您可以子类化 DatabaseCache
以创建您自己的自定义后端。添加一个方法,允许您通过前缀查询键,或通过前缀删除键,然后将其包装到管理命令中以便于访问。
假设您使用 MySQL 作为您的数据库后端,DatabaseCache 的这个子 class 应该工作于 return 缓存键上 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"}
我正在使用 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_" 的所有键?
Django 的缓存 API 不提供您正在寻找的内容,因此 none 的实现也可以。一种解决方案是创建自己的后端。
您仍然需要处理一些 SQL 查询,但您可以子类化 DatabaseCache
以创建您自己的自定义后端。添加一个方法,允许您通过前缀查询键,或通过前缀删除键,然后将其包装到管理命令中以便于访问。
假设您使用 MySQL 作为您的数据库后端,DatabaseCache 的这个子 class 应该工作于 return 缓存键上 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"}