2011-02-18 2 views
3

테스트 목적으로 장고가 자동으로 select_related() 호출에 지정되지 않은 관련 테이블을 자동으로 가져 오지 않도록하려면 어떻게해야합니까?Django - 자동 관련 테이블 불러 오기 방지

쿼리 중에 관련 모델 데이터를 가져 오기 위해 select_related()를 많이 사용하는 대규모 응용 프로그램이 있습니다. 모든 select_related() 호출은 기본값에 의존하기보다는 특정 관련 모델을 지정하는 데 사용됩니다. select_related ('foo는', '바', 'foo__bar') 응용 프로그램으로

장고 행복하게 와 친절로 도망 간다 어디 시나리오의 수를 떠나 select_related 통화 이 완전히 유지하지 않은, 성장했습니다 관련 모델 행을 가져 오는 데이터베이스 이것은 데이터베이스 히트 수를 상당히 증가시킵니다. 분명히 원하지 않습니다.

나는 django.db.connection.queries 컬렉션을 사용하여 생성 된 쿼리를 확인하여이를 추적하는 데 성공했지만 일부는 으로 남아 있습니다.

django 코드에서 적절한 패치 위치를 찾으려고 시도 했으므로이 시나리오에서는 예외가 발생하여 추적이 훨씬 쉬워졌지만 코드가 손실되는 경향이 있습니다.

감사합니다.

+0

개발을 위해 장고 디버그 도구 모음을 사용하는 것이 좋습니다. 그것은 (쿼리의 총 수와 실행 된 각각의 쿼리와 같이) 상세하게 데이터베이스에서 실행 된 쿼리를 보여줍니다. https://github.com/robhudson/django-debug-toolbar – FallenAngel

+0

@FallenAngel, 팁 주셔서 감사합니다. 사용하지 않았습니다. 전에 디버그 도구 모음과 그것은 엄청나게 유용합니다. –

답변

1

더 많은 파기가 끝나면 코드에서 코드를 찾아 냈습니다.

문제의 파일은 장고/DB/모델/필드/related.py

이 파일에 두 줄을 삽입해야

입니다.

클래스 "SingleRelatedObjectDescriptor"를 찾습니다. 에 __() 다시 __get 변경해야

def __get__(self, instance, instance_type=None): 
    if instance is None: 
     return self 
    try: 
     return getattr(instance, self.cache_name) 
    except AttributeError: 
     raise Exception("Automated Database Fetch on %s.%s" % (instance._meta.object_name, self.related.get_accessor_name())) 
     # leave the old code here for when you revert! 

마찬가지로 코드 더 아래 "ReverseSingleRelatedObjectDescriptor"클래스에서, : 다음과 같이() 함수 __get의 __을 변경해야

def __get__(self, instance, instance_type=None): 
    if instance is None: 
     return self 

    cache_name = self.field.get_cache_name() 
    try: 
     return getattr(instance, cache_name) 
    except AttributeError: 
     raise Exception("Automated Database Fetch on %s.%s" % (instance._meta.object_name, self.field.name)) 
     # BEWARE: % parameters are different to previous class 
     # leave old code here for when you revert 

당신이 한 번 이 작업을 수행하면 Django가 자동 데이터베이스 조회를 수행 할 때마다 예외가 발생한다는 것을 알 수 있습니다. 이것은 처음 시작할 때 매우 짜증나지만, 성가신 데이터베이스 조회를 추적하는 데 도움이됩니다. 분명히, 그것들을 모두 발견했을 때 데이터베이스 코드를 다시 정상으로 되 돌리는 것이 가장 좋습니다. 필자는 라이브 프로덕션 코드가 아닌 디버깅/성능 조사 단계에서이를 사용하는 것이 좋습니다.

0

그렇다면 특정 방법으로 수행 할 수있는 방법을 중단하는 방법을 묻는 중입니다. 왜 그렇게하고 싶지는 모르겠다.

그러나 select_related에 대해 알아야 할 사항 중 하나는 null=True으로 정의 된 관계를 자동으로 따르지 않는다는 것입니다. 따라서 FK를 지금까지 설정할 수 있다면 그 관계는 따르지 않을 것입니다.

+0

이것은 쿼리를 최적화 할 때 정말로 중요합니다. 각 자동 가져 오기는 비용이 많이 들고 선택 관련을 사용하여 피해야합니다. 그러나 가져와야하는 최소한의 항목을 파악하는 것은 종종 약간 까다 롭습니다. 이 상황에서 오류를 얻는 것이 훨씬 더 바람직합니다. –