database - english - ¿Cómo deshabilitar el caché de consultas de Django?
django rest framework cache (5)
El caché de consultas solo se aplica dentro de un QuerySet. En otras palabras, si evalúa dos veces el mismo objeto de conjunto de consulta, funcionará el almacenamiento en caché de consultas. Pero si está haciendo una consulta cada 10 segundos, presumiblemente esto es a través de un cron que genera un nuevo proceso cada vez, por lo que no hay forma de que Django guarde en caché nada.
Es posible que el propio caché de su base de datos entre en funcionamiento si repetidamente realiza exactamente la misma consulta. Debería ver la documentación de su DBMS para ver cómo administrarla correctamente.
En mi aplicación Django, ejecuto repetidamente la misma consulta en mi base de datos (por ejemplo, cada 10 segundos). Luego creo una suma de MD5 sobre el conjunto de preguntas que recibo y lo comparo con la suma de MD5 que creé en la ejecución anterior. Si ambos son iguales, los datos no han cambiado y la página web no necesita actualización.
Mientras hago esto, los datos en el DB pueden cambiar.
Sin embargo, la consulta devuelve el mismo queryset, aparentemente debido al almacenamiento en caché de consultas .
¿Cómo puedo desactivar el caché de consultas y ejecutar explícitamente la consulta en el DB?
El enlace que proporciona a la Documentación de Django implica que lo siguiente:
>>> print [e.headline for e in Entry.objects.all()]
>>> print [e.pub_date for e in Entry.objects.all()]
crea dos consultas a la base de datos, mientras que:
>>> queryset = Poll.objects.all()
>>> print [p.headline for p in queryset] # Evaluate the query set.
>>> print [p.pub_date for p in queryset] # Re-use the cache from the evaluation.
utiliza el caché de consultas, ya que está accediendo a los mismos resultados de evaluación.
Encontré este problema en django versión 1.8. No hay una manera directa de hacerlo, pero hay algunas maneras de hacer que el conjunto de consulta se reevalúe y ejecute accediendo a db en lugar de a la caché. Lo encontré en la documentación de Django Queryset
Usé uno de ellos para manejar mi problema. Es la función exists()
de los conjuntos de consulta. len()
y repr()
también se pueden usar. Ellos trabajaron para mí también.
Ejemplo
queryset = ModelClass.objects.filter(....)
queryset.exists()
#or len(queryset)
#or repr(queryset)
#Now queryset is re-evaluated.
Encontré un comportamiento que pensé que era una especie de almacenamiento en caché, pero resultó ser que las transacciones de la base de datos me engañaban.
Tuve el problema de que en otro proceso, los elementos se agregaban a la base de datos y quería supervisar el progreso del otro proceso, así que abrí un shell django y emití lo siguiente:
>>> MyData.objects.count()
74674
>>> MyData.objects.count()
74674
El valor no estaba cambiando, aunque realmente estaba en la base de datos. Me di cuenta de que, al menos con la configuración de MySQL y django, estaba en una transacción y solo veía una "instantánea" de la base de datos en el momento en que abría la transacción.
Dado que con las vistas en django, tenía el comportamiento de autocommitido definido, esto estaba bien para que cada vista solo viera una instantánea, ya que la próxima vez que se llamara a una vista sería en una transacción diferente. Pero para un fragmento de código que no se estaba confirmando automáticamente, no vería ningún cambio en el db, excepto los que se realizaron en esta transacción.
Solo pensé en arrojar esta respuesta para cualquier persona que se encuentre con esta situación.
Para resolver, comprometa su transacción, que se puede hacer manualmente de esta manera:
>> from django.db import transaction
>> transaction.enter_transaction_management()
>> transaction.commit() # Whenever you want to see new data
Muchas gracias por sus respuestas, sus respuestas me hicieron dar unos pasos atrás y volver a pensar.
Para probar el almacenamiento en caché en un nivel de DBMS, me alejé de Django y usé un script de shell que, de todos modos, tenía a mano para consultar datos de un DB de SQLite, mientras añadía datos en una segunda sesión de shell. Los nuevos datos aparecieron en las consultas periódicas justo después de que los agregué, por lo que no hay caché de consultas aquí.
Esto se redujo a la parte de Django. El código involucrado no es muy complejo y una pequeña salida de registro y una revisión del código revelaron el problema: la consulta utilizada para obtener el conjunto de consulta usado para crear la suma MD5 tenía un error y siempre estaba vacía. Por lo tanto, la suma de MD5 siempre fue la misma. De hecho, parecía un resultado en caché: los datos están cambiando, pero el conjunto de preguntas permanece igual. El problema no se muestra en la aplicación, ya que se utilizó una consulta diferente para obtener los datos que se muestran allí.
Lección aprendida: si estás completamente desconcertado, da un paso atrás y vuelve a pensar en tus suposiciones.
¡Gracias de nuevo! :-)