Доступ к данным Johnny Cache
Я относительно новичок в Python, и мне было интересно, можно ли получить доступ к результатам, кэшированным Johnny Cache, для дальнейшей обработки, прежде чем возвращать результат, например, для выполнения дальнейших запросов к нему.
В качестве упрощенного примера рассмотрим таблицу с сотнями тысяч спортивных результатов, каждый из которых классифицируется по виду спорта, например, теннис, футбол, гольф и т. Д. Некоторые пользователи интересуются только футболом и гольфом, поэтому в настоящее время мы используем кэш johnny для кеширования. результаты запроса по каждой спортивной категории за 30 мин. Однако мы не можем передать эти данные как есть пользователю, так как это требует дальнейшей фильтрации для предпочтений пользователя (например, они хотят получить результаты только для определенных команд / игроков). Выполнение вызова базы данных для категории и пользовательских настроек было бы непозволительно, поэтому мы кешируем часть запроса (спортивную категорию), которая составляет основу всех запросов, но теперь мы хотим отфильтровать этот кэш в памяти для пользователя. предпочтения - можно ли это сделать с помощью Джонни Кэша, и если да, то как, пожалуйста?
1 ответ
Короткий ответ - да, но вы не сможете использовать фильтры QuerySet, не вызвав еще один вызов базы данных. Вам нужно будет перебирать возвращаемые результаты, чтобы избежать попадания в базу данных. Это зависит от того, хотите ли вы сделать это или нет, в зависимости от размера возвращаемых результатов и времени запроса для нового отфильтрованного запроса.
Как уже упоминалось в QuerySet
документация, отфильтрованный QuerySet возвращает новый QuerySet, который не связан с оригиналом.
Чтобы понять ситуацию дальше, вы можете посмотреть на сигналы johnny.signals.qc_hit
а также johnny.signals.qc_miss
чтобы увидеть, когда он делает вызов базы данных. Сигналы - это механизм django для привязки обратных вызовов к определенным событиям. В этом случае Джонни Кэш выставляет эти два полезных сигнала.
Я создал простое приложение, чтобы протестировать его и помочь продемонстрировать это поведение.
models.py
from django.db import models
class TestModel(models.Model):
prop_a = models.TextField()
prop_b = models.TextField()
def __unicode__(self):
return "{} {}".format(self.prop_a, self.prop_b)
views.py
from django.dispatch import receiver
from django.http import HttpResponse
from johnny.signals import qc_hit, qc_miss
from models import TestModel
def index(self):
objs = TestModel.objects.all()
print objs
print objs.filter(prop_a='a') #Causes another database or cache hit
return HttpResponse("success")
def generate(self):
generate_data()
return HttpResponse("generated")
def generate_data():
properties = [ 'a', 'b', 'c', 'd', 'e']
for i in xrange(len(properties)):
for j in xrange(len(properties)):
test_model = TestModel(prop_a=properties[i], prop_b=properties[j])
test_model.save()
@receiver(qc_hit)
def cache_hit(sender, **kwargs):
print "cache hit"
@receiver(qc_miss)
def cache_miss(sender, **kwargs):
print "cache miss"
Поскольку Johnny Cache выполняется с помощью промежуточного программного обеспечения, вам необходимо протестировать его с помощью представления, поскольку это происходит от запроса к ответу. В приведенном выше случае, у нас есть очень простая модель, которую мы смотрим на все TestModel
объекты, а затем отфильтрованный результат. Выходные данные будут отображать каждый из них, первоначально вызывающий пропадание кеша, а затем - попадание в кеш. Они не связаны и рассматриваются как два отдельных запроса.
Однако, если вы делаете что-то вроде
objs = TestModel.objects.all()
result = []
for obj in objs:
if obj.prop_a == 'a':
result.append(obj)
Вы увидите только одно попадание в базу данных / кэш Джонни. Очевидно, что это дает желаемый результат, но может быть или не быть медленнее, чем другой запрос, в зависимости от размера исходного запроса.
Я надеюсь, что это поможет ответить на ваш вопрос, а также даст вам представление о том, как кеширование работает дальше.