2011-05-28 12 views
11

Tengo un sitio bastante simple en el que estoy usando el decorador page_cache. Tengo un cronjob que busca nuevos datos y los procesa si está disponible. (Esto se ejecuta utilizando comandos de gestión ejecutados con crontab)Cómo borrar todo el caché al usar el decorador page_cache de django

Quiero borrar todos los cachés de página cuando se procesan datos nuevos.

estoy mirando a la documentación aquí: https://docs.djangoproject.com/en/dev/topics/cache/?from=olddocs?from=olddocs

y encontró cache.clear(), que parece ser lo que quiero. He agregado un indicador a la parte de procesamiento de datos y ejecuto cache.clear() cuando se encuentran nuevos datos.

Sin embargo, después de ejecutar el comando, la caché no se borra. (He borrado el navegador en caché y verificado para asegurarse de que no es el navegador)

¿No funciona cache.clear() para borrar todas las páginas almacenadas en caché?

Estoy usando el DatabaseCache, así que supongo que podría entrar y borrar la tabla de caché manualmente, pero ¿hay alguna otra manera mejor?

Respuesta

12

He tenido este problema con una caché de base de datos SQLite - el método clear() no borra la caché aunque funciona bien con una caché de base de datos MySQL. Parece que un caché de SQLite necesita una llamada al django.db.transation.commit_unless_managed() después de ejecutar la instrucción DELETE from [table].

He estado usando múltiples cachés desde antes de añadir el apoyo oficial en el núcleo como parte de 1.3 y así tienen una envoltura alrededor de varios de la caché de llamadas - incluyendo clear() - por lo que yo era capaz de reemplazar este método e incluyen la commit_unless_managed(). Creo que probablemente debería registrarlo como un error.

Aquí está el esquema del código que estoy usando para limpiar un caché Memcache (la caché de forma predeterminada en django.core.cache) y una caché de base de datos almacenada en el cache_table de la base de datos settings.DATABASES['cache_database'].

from django.db import connections, transaction 
from django.core.cache import cache # This is the memcache cache. 

def flush(): 
    # This works as advertised on the memcached cache: 
    cache.clear() 
    # This manually purges the SQLite cache: 
    cursor = connections['cache_database'].cursor() 
    cursor.execute('DELETE FROM cache_table') 
    transaction.commit_unless_managed(using='cache_database') 

En lugar de ser vago y difícil de codificación de la manera que tengo que debería ser bastante fácil de conseguir los valores de settings.CACHES y django.db.router.

1

Ponga algo en la memoria caché, luego intente llamar al cache.clear() desde la consola manage.py shell y luego verifique manualmente el contenido de la memoria caché de la base de datos. Si eso funciona, tal vez su cache.clear() simplemente no se llame cuando se encuentren nuevos datos.

La forma más fácil de entender lo que está pasando bajo el capó se acaba de poner import pdb; pdb.set_trace() al principio de la función cache.clear(), a continuación, ejecutar el servidor de depuración y esperar, a continuación, algunos llaman código de este Func podrás ejecutar paso- paso a paso su código o simplemente verá que este func no se llama como se esperaba.

+0

Comprobé con el shell, e incluso cuando ejecuto cache.clear() desde el shell, parece que no borra el caché. Sin embargo, parece que se borra en función del período de caducidad configurado ... – monkut

+0

El método 'clear' de backend de caché de base de datos es bastante simple: https://code.djangoproject.com/browser/django/tags/releases/1.3/ django/core/cache/backends/db.py # L138 Simplemente borra todos los registros de la tabla de caché. ¿Estás seguro de que tu caché está configurada correctamente? ¿Tal vez usas memcached o algo más? Otra razón podría ser la memoria caché del navegador, para asegurarse de que pueda abrir su sitio web en otro navegador que aún no haya utilizado para buscar ese sitio. –

+0

lorien, gracias, intentaré verificar la configuración – monkut

4

Es un error #19896 que parece corregido en 1.6.

Si está utilizando una versión anterior, hacer algo como lo siguiente debería hacer que el trabajo funcione como se esperaba.

from django.db import router, transaction 


def clear_cache(the_cache): 
    the_cache.clear() 
    # commit the transaction 
    db = router.db_for_write(the_cache.cache_model_class) 
    transaction.commit_unless_managed(using=db) 

Esto simplemente se asegura de que la transacción se comprometa.

Cuestiones relacionadas