2016-06-03 1 views
2

Je suis mise en cache des résultats de calcul dans une application Django à l'aide du cache de base de données Django (https://docs.djangoproject.com/en/1.8/topics/cache/#database-caching).clés dans Énumération Database Cache Django

Quel est le moyen d'énumérer toutes les clés stockées dans le cache à un moment donné. Parfois, je dois invalider (supprimer) des parties du cache avant l'expiration (parce que je débogue). Les clés de cache sont générées par un calcul élaboré et je ne veux pas répéter ce calcul. Je connais le préfixe des clés de cache que je voudrais supprimer mais je ne connais pas les chaînes de caractères complètes.

Je ne vois pas tout de suite sur l'API cache comment pourrais-je faire cela. Je peux obtenir des entrées, créer des clés, supprimer des entrées et effacer tout le cache: https://docs.djangoproject.com/en/1.8/topics/cache/#the-low-level-cache-api

Maintenant, je dois extraire les clés avec des instructions SQL qui est un PITA. J'aimerais écrire une commande de gestion que je peux utiliser pour invalider des sections.


Exemple:

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', 
    } 
} 

J'ai créé le cache comme expliqué dans la documentation Django I LIÉ. Placer des données dans le cache (pas d'expiration: je contrôle les entrées).

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) 

Et voici la question: comment puis-je trouver toutes les clés du cache qui a le préfixe clé « b_ » à un moment donné?

+1

Cela devrait être possible. Si vous ajoutez votre code existant à la question, il vous sera plus facile de comprendre exactement ce que vous voulez réaliser et de suggérer des moyens alternatifs. –

+0

Ok, j'ai ajouté un exemple. –

Répondre

1

En supposant que vous utilisez MySQL comme backend de base de données, cette sous-classe de DatabaseCache devrait fonctionner pour retourner un dictionnaire de tous les résultats d'une requête de type LIKE sur les clés de cache.

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 

Ensuite il vous suffit de changer le backend enregistré dans votre settings.py

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

Exemple:

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

API de cache de Django n'offre pas ce que vous cherchez, si aucune des implémentations non plus. Une solution serait de créer votre propre backend.

Vous allez toujours devoir contourner certaines requêtes SQL, mais vous pouvez sous-classer DatabaseCache pour créer votre propre backend personnalisé. Ajoutez une méthode qui vous permet de rechercher des clés par préfixe ou de les supprimer par préfixe, puis de les placer dans une commande de gestion pour y accéder facilement.