Remove all matching keys from Django cache

4.1k Views Asked by At

I need to iterate through my server's cache, which is a LocMemCache object, and remove every key in the cache that begins with the string 'rl:'. From what I understand, the only functions that the caching API django provides are get, set, and delete. Here is a rough example of what I am trying to do:

def clear_ratelimit_cache():
    if any('rl:' in s for s in cache.get(s)): 
        log.info(
            'FOUND SOMETHING') 
        cache.delete(*something else here*)

Trying to do this, however, gives me a NameError, stating that global name 's' is not defined. Also it must be noted that the cache is not iterable. Has anyone worked with the cache in a similar manner, and has a suggestion?

3

There are 3 best solutions below

1
On

One option would be to have a separate, named cache in your configuration just for this data type, and then call its clear() method.

Otherwise, Django LocMemCache stores items in a simple dict, in the instance's _cache attribute. Since they don't give you an API for this, you can simply remove the items directly:

for key in cache._cache.keys():
    if key.startswith('rl:'):
        del cache._cache[key]

Usual disclaimer, this is an implementation detail that won't work with other cache types.

0
On

... in s for s in cache.get(s) can't possibly work. There's no way to determine what possible values s could have.

The short answer is that there's no way to do this with the standard cache API without some changes to your data model. As another answer suggests, you could use a separate cache for just these values. Alternatively, you could have a cache key which stores the keys which start with rl: so you know what to delete.

The problem is that many cache backends don't actually have a way to find cache keys matching a particular value aside from iterating over all the keys. You probably don't want to do this anyway, since it can get quite expensive as your cache size grows.

0
On

With LocMemCache, you can delete all the cache values whose keys start from rl: as shown below. *list() is needed for cache._cache.keys() otherwise you get error and specifying a version is needed for cache.delete() otherwise you cannot delete all the cache values whose keys start from rl: and the answer of my question explains the default version of a cache value with LocMemCache:

        # `list()` is needed
for key in list(cache._cache.keys()):
    new_key = key.split(":", 2)[2]
    version = key.split(":", 2)[1]

    if new_key.startswith('rl:'):
        cache.delete(new_key, version=version)