Python 访问Johnny缓存数据

Python 访问Johnny缓存数据,python,django,django-johnny-cache,Python,Django,Django Johnny Cache,我对Python比较陌生,我想知道在返回结果之前是否可以访问Johnny Cache缓存的结果进行进一步处理,例如对其运行进一步的查询 作为一个简化的例子,考虑到我们有一个有成千上万个运动结果的表格,每一个都被一个运动分类,例如网球、足球、高尔夫球等。一些用户只对足球和高尔夫感兴趣,所以现在我们使用JNNY Cache来缓存每一个运动类别的查询结果30分钟。但是,我们不能按原样将此数据传递给用户,因为它需要进一步过滤用户的偏好(例如,他们只需要特定球队/球员的结果)。对类别和用户首选项执行db调

我对Python比较陌生,我想知道在返回结果之前是否可以访问Johnny Cache缓存的结果进行进一步处理,例如对其运行进一步的查询


作为一个简化的例子,考虑到我们有一个有成千上万个运动结果的表格,每一个都被一个运动分类,例如网球、足球、高尔夫球等。一些用户只对足球和高尔夫感兴趣,所以现在我们使用JNNY Cache来缓存每一个运动类别的查询结果30分钟。但是,我们不能按原样将此数据传递给用户,因为它需要进一步过滤用户的偏好(例如,他们只需要特定球队/球员的结果)。对类别和用户首选项执行db调用是禁止的,这就是为什么我们缓存查询的一部分(运动类别),它构成了所有请求的基础,但现在想在内存缓存中进一步过滤用户的首选项-这可以用Johnny cache完成吗?如果可以,请怎么做?

简短的回答是肯定的,但是如果不引起另一个数据库调用,您将无法使用QuerySet筛选器。您需要遍历返回的结果,以避免数据库被命中。这取决于您是否希望根据返回结果的大小和新筛选查询的查询时间执行此操作

QuerySet
文档中所述

为了进一步了解情况,您可以查看signals
johny.signals.qc\u hit
johny.signals.qc\u miss
以查看它何时进行数据库调用。是一种django机制,用于将回调绑定到某些事件。在本例中,Johnny Cache公开了这两个有用的信号

我创建了一个简单的应用程序来测试它,并帮助演示这种行为

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)
您只会看到一次对数据库/johnny缓存的命中。显然,这会得到您想要的结果,但可能会比另一个查询慢,也可能不会慢,这取决于初始查询的大小


我希望这有助于回答您的问题,并为您提供一种进一步了解缓存工作原理的方法。

您是说还希望缓存用户特定的结果吗?如果是这样的话,为什么不直接使用原始查询(我知道您说过这是禁止的,但是以这种迂回的方式进行查询对我来说似乎更为禁止,尽管我不知道数据库索引、大小等的细节)?如果没有,我就看不出问题所在,因为您总是在动态修改缓存的体育查询。@ubomb我不想缓存用户特定的结果。我想查询缓存的常规结果。对。既然Johnny Cache会自动缓存体育查询,那么这不是一个关于如何过滤查询结果集的问题吗?完全独立于Johnny Cache?在这种情况下,同样需要了解更多关于实际数据库的信息。是否还有其他未回答的问题?QuerySet方法,例如
filter
修改django生成的sql以执行查询。如果您想避免数据库命中并进一步处理它,那么需要在django的ORM之外进行。