Skip to main content
 首页 » 编程设计

python之枚举 Django 数据库缓存中的键

2024年08月22日28telwanggs

我正在使用 Django 数据库缓存 ( https://docs.djangoproject.com/en/1.8/topics/cache/#database-caching ) 在 Django 应用程序中缓存一些计算结果。

在给定时刻枚举存储在缓存中的所有键的方法是什么。有时我需要在缓存过期之前使(删除)部分缓存失效(因为我正在调试)。缓存键是通过精心计算生成的,我不想重复该计算。我知道要删除的缓存键的前缀,但不知道完整的键字符串。

我没有立即在缓存 API 上看到我该怎么做。我可以获取条目、创建 key 、删除条目并清除整个缓存:https://docs.djangoproject.com/en/1.8/topics/cache/#the-low-level-cache-api

现在我必须使用 SQL 语句提取 key ,这是一个 PITA。我想编写可用于使部分无效的管理命令。


例子:

设置.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_”的所有键?

请您参考如下方法:

假设您使用 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"}