python - 访问 Johnny 缓存数据

标签 python django django-johnny-cache

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

作为一个简化的示例,假设我们有一个包含数十万个运动结果的表,每个结果都按一项运动进行分类,例如体育运动。网球、足球、高尔夫等。有些用户只对足球和高尔夫感兴趣,因此目前我们使用 johnny 缓存来缓存每个运动类别的查询结果 30 分钟。但是,我们无法将这些数据按原样传递给用户,因为它需要进一步过滤用户的偏好(例如,他们只想要某些球队/球员的结果)。对类别和用户首选项进行数据库调用是令人望而却步的,这就是为什么我们缓存构成所有请求基础的查询部分(运动类别),但现在希望进一步过滤内存中的缓存以供用户使用首选项 - 这可以通过 Johnny Cache 完成吗?如果可以,请问如何完成?

最佳答案

简短的回答是肯定的,但是您将无法使用 QuerySet 过滤器而不导致另一次数据库调用。您需要迭代返回的结果以避免数据库命中。这取决于您是否要根据返回结果的大小和新过滤查询的查询时间来执行此操作。

QuerySet 文档中所述,a filtered QuerySet returns a new QuerySet that isn't bound by the original .

要进一步了解情况,您可以查看信号 johnny.signals.qc_hitjohnny.signals.qc_miss 以了解何时进行数据库调用。 Signals是一种将回调绑定(bind)到某些事件的 django 机制。在这种情况下,Johnny Cache 公开了这两个有用的信号。

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

模型.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)

View .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 是通过中间件完成的,因此您需要通过 View 来测试它,因为它是从请求到响应发生的。在上面的例子中,我们有一个非常简单的模型,我们正在查看所有 TestModel 对象,然后查看过滤结果。输出将显示每个最初导致缓存未命中,然后导致缓存命中的情况。它们不相关,被视为两个单独的查询。

但是,如果你做了类似的事情

objs = TestModel.objects.all()
result = []
for obj in objs:
   if obj.prop_a == 'a':
      result.append(obj)

您只会看到对数据库/johnny 缓存的一次命中。显然,这会得到您想要的结果,但可能会或可能不会比另一个查询慢,具体取决于初始查询的大小。

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

关于python - 访问 Johnny 缓存数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19644314/

相关文章:

python - 我如何在 Django 中定义 3 个以上模型之间的多对多关系?

python - View 中的 Django 过滤器

mysql - Django mysql count distinct 给 postgres 不同的结果

python - 通过直方图测量图像的颜色

python - SVN pre-commit hook 拒绝标签使用不一致的 Python 文件

python - 我可以使用 XLRD 密码保护 excel 工作簿吗?

python - python可以告诉我在当前 block 中定义了一个类的哪些属性吗?