2013-10-28 3 views
2

저는 Python을 처음 사용하여 결과를 반환하기 전에 추가 처리를 위해 Johnny Cache에서 캐시 된 결과에 액세스 할 수 있는지 궁금합니다. 그것에 대한 추가 쿼리를 실행합니다.Johnny Cache 데이터에 액세스

단순화 된 예로, 수십만 개의 스포츠 결과가있는 테이블이 스포츠별로 분류되어 있다고 가정 해 보겠습니다. 일부 사용자는 축구 & 골프에만 관심이 있으므로 현재 조니 캐시를 사용하여 30 분 동안 각 스포츠 카테고리에 대한 쿼리 결과를 캐시합니다. 그러나 사용자의 환경 설정에 대한 추가 필터링이 필요하므로 (예 : 특정 팀/플레이어에 대한 결과 만 필요함)이 데이터를 사용자에게 그대로 전달할 수는 없습니다. 카테고리 및 사용자 환경 설정에 대한 db 호출을 수행하는 것은 금지됩니다. 따라서 우리는 모든 요청의 기본을 이루는 쿼리 부분 (스포츠 카테고리)을 캐시하지만 사용자의 메모리 캐시를 더 필터링하려고합니다 환경 설정 - 조니 캐시로 할 수 있습니까? 그렇다면 어떻게해야합니까?

+0

사용자 별 결과도 캐시하고 싶습니다. 그렇다면 원래 쿼리를 만드는 것만으로도 충분합니다 (데이터베이스 인덱스의 특성을 알지 못하더라도이 방법이 너무 길다는 것을 알았습니다. 크기 등)? 그렇지 않은 경우 어쨌든 캐시 된 스포츠 쿼리를 항상 수정해야하기 때문에 문제가 실제로 표시되지 않습니다. – ubomb

+0

@ubomb 사용자 특정 결과를 캐시에 저장하지 마십시오.캐싱 된 일반적인 결과를 쿼리하고 싶습니다. – RunLoop

+0

오른쪽. Johnny Cache는 자동으로 스포츠 쿼리를 캐시하므로, 조니 캐시와 완전히 별개로 해당 쿼리에서 결과 집합을 필터링하는 방법에 대한 질문이 아닌가? 다시 실제 데이터베이스에 대해 더 많이 알고 있어야합니다. – ubomb

답변

5

답은 간단하지만 다른 데이터베이스 호출을 발생시키지 않고 쿼리 세트 필터를 사용할 수는 없습니다. 데이터베이스가 손상되지 않도록 반환 된 결과를 반복해야합니다. 반환 된 결과의 크기와 새 필터링 된 쿼리의 쿼리 시간에 따라이 작업을 수행할지 여부를 결정합니다.

QuerySet 설명서에 언급 된대로 a filtered QuerySet returns a new QuerySet that isn't bound by the original.

상황을 더 잘 이해하려면 johnny.signals.qc_hitjohnny.signals.qc_miss 신호를보고 데이터베이스 호출을 확인하십시오. Signals은 콜백을 특정 이벤트에 바인드하는 장고 메커니즘입니다. 이 경우 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" 

조니 캐시 미들웨어를 통해 이루어집니다대로 응답 요청에서 발생하기 때문에, 당신은보기를 통해 테스트해야합니다 . 위의 경우 우리는 매우 간단한 모델을 가지고 있습니다. 우리는 모든 TestModel 개체를 살펴본 후 필터링 된 결과를 보았습니다. 출력에는 처음에는 캐시 미스가 발생하고 이후에는 캐시 히트가 발생합니다. 그것들은 관련이 없으며 두 개의 별도의 질의로 간주됩니다. 당신이

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

뭔가를 할 경우

그러나, 당신은 데이터베이스/조니 캐시 하나 개의 히트를 볼 수 있습니다. 분명히 이것은 원하는 결과를 얻지 만 초기 쿼리의 크기에 따라 다른 쿼리보다 느려지거나 느리지 않을 수도 있습니다.

이 질문이 답변으로 도움이되고 캐싱이 더 잘 작동하는 방식을 이해할 수 있기를 바랍니다.