2016-06-03 24 views
2

Ich cache einige Berechnungsergebnisse in einer Django-Anwendung mit Django-Datenbank-Cache (https://docs.djangoproject.com/en/1.8/topics/cache/#database-caching).Schlüssel in Django-Datenbank-Cache aufzählen

Wie werden alle Schlüssel aufgelistet, die zu einem bestimmten Zeitpunkt im Cache gespeichert sind? Gelegentlich muss ich Teile des Caches vor dem Ablauf ungültig machen (löschen), da ich gerade debugge. Die Cache-Schlüssel werden durch aufwendige Berechnungen erzeugt, und ich möchte diese Berechnung nicht wiederholen. Ich kenne das Präfix der Cache-Schlüssel, die ich löschen möchte, aber ich kenne die vollständigen Schlüsselzeichenfolgen nicht.

Ich sehe nicht sofort auf der Cache-API, wie könnte ich das tun. Ich kann Einträge erhalten, Schlüssel erstellen, Einträge löschen und den gesamten Cache löschen: https://docs.djangoproject.com/en/1.8/topics/cache/#the-low-level-cache-api

Im Moment muss ich die Schlüssel mit SQL-Anweisungen extrahieren, die eine PITA ist. Ich möchte einen Verwaltungsbefehl schreiben, den ich verwenden kann, um Abschnitte ungültig zu machen.


Beispiel:

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

I Cache erzeugt wie in der Dokumentation Django erläutert I verknüpft. Einige Daten in den Cache legen (kein Ablauf: Ich kontrolliere die Einträge).

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) 

Und hier ist die Frage: Wie kann ich alle Schlüssel im Cache zu finden, die den Schlüssel Präfix „B_“ zu einem bestimmten Zeitpunkt hat?

+1

Dies sollte möglich sein. Wenn Sie Ihren vorhandenen Code zu der Frage hinzufügen, wird es einfacher sein, genau zu verstehen, was Sie erreichen möchten, und alternative Wege vorschlagen. –

+0

Ok ich habe ein Beispiel hinzugefügt. –

Antwort

1

Angenommen, Sie verwenden MySQL als Ihr DB-Backend, sollte diese Unterklasse des DatabaseCache arbeiten, um ein Wörterbuch aller Ergebnisse aus einer LIKE-Typ-Abfrage auf Cache-Schlüssel zurückzugeben.

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 

Dann brauchen Sie nur den registrierten Backend in Ihrer settings.py

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

Beispiel zu ändern:

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

Djangos Cache-API bietet nicht das, was Sie suchen, also auch keine der Implementierungen. Eine Lösung wäre, ein eigenes Backend zu erstellen.

Sie werden immer noch einige SQL-Abfragen mucksen müssen, aber Sie können die Unterklasse DatabaseCache erstellen, um Ihr eigenes benutzerdefiniertes Backend zu erstellen. Fügen Sie eine Methode hinzu, mit der Sie Schlüssel nach Präfix abfragen oder nach Präfix löschen können, und dann für einen einfachen Zugriff in einen Verwaltungsbefehl umbrechen.