2017-12-23 4 views
1

나는 (배치 ML을 위해) 5 백만 + 항목의 의 검색어를 처리하고 난 내가 오직 필요로의 검색어을 평가하지 않고의 검색어 (그래서 멀티 스레딩 작업을 수행 할 수 있습니다) 을 분할해야 한 번 쿼리 세트의 각 항목에 액세스하므로 원인을 평가하는 쿼리 세트 항목을 캐시하지 않으려 고합니다.어떻게 평가하지 않고 장고 쿼리 세트를 분할합니까?

항목을 하나의 쿼리 세트로 선택하고 평가하지 않고 분할 할 수 있습니까? 또는이 문제를 해결하기 위해 Limits [: size]를 사용하여 여러 쿼리 세트를 쿼리하여 접근해야합니까?

NB : 내가에서 Iterable을 평가하지 않고의 검색어를 순환 사용할 수 있지만 내 질문은 다음의 각 상에 반복자를 실행하는 (가능한 경우) 내가이 검색어 세트를 분할 할 수있는 방법과 관련이 있음을 알고 분할 된 querysets.

+1

반복하여 작업자 스레드에서 작업을 가져올 수 있습니까? 그것은 Django를 통해 단일 쿼리로 작업하는 것을 상상할 수있는 유일한 방법입니다. (꽤 많이 방금 threadsafe 반복자를 전달합니다.) – Ryan

+1

django 쿼리는 무언가 강제 평가를받을 때까지 평가되지 않습니다. 그리고 그것은 썰어 질 수 있습니다. 따라서 myQuery [1000 : 11000]는 쿼리의 일부분을 매우 깨끗하게 제공합니다. 아니요, 전체를 평가하지는 않습니다. –

답변

4

장고 당신이 매겨진 데이터를 관리 할 수 ​​있도록 몇 가지 클래스를 제공합니다 - 즉을, 데이터를 여러 페이지에 걸쳐 분할 것, "이전/다음"링크 :

from django.core.paginator import Paginator 

object_list = MyModel.objects.all() 
paginator = Paginator(object_list, 10) # Show 10 objects per page, you can choose any other value 

for i in paginator.page_range(): # A 1-based range iterator of page numbers, e.g. yielding [1, 2, 3, 4]. 
    data = iter(paginator.get_page(i)) 
    # use data 
+1

나는 paginator가 최고의 해결책 인 것 같은 나의 문제를 믿는다. N.B. : 페이지의 항목을 읽는 사람은 요청할 때까지 평가되지 않습니다. 즉, 게으른 평가 – bmjrowe

1

당신이 할 수있는 예, 업데이트 된 대답은 당이 gist

에서 같은 :

def queryset_iterator(queryset, chunk_size=1000): 
""" 
Iterate over a Django Queryset ordered by the primary key 
This method loads a maximum of chunk_size (default: 1000) rows in it's 
memory at the same time while django normally would load all rows in it's 
memory. Using the iterator() method only causes it to not preload all the 
classes. 
Note that the implementation of the iterator does not support ordered query sets. 
""" 
    try: 
     last_pk = queryset.order_by('-pk')[:1].get().pk 
    except ObjectDoesNotExist: 
     return 

    pk = 0 
    queryset = queryset.order_by('pk') 
    while pk < last_pk: 
     for row in queryset.filter(pk__gt=pk)[:chunk_size]: 
      pk = row.pk 
      yield row 
     gc.collect() 
1

통과 쿼리는 스레드로 설정 내가 추천할만한 것이 아니다. 나는 당신이하려고하는 일과 그 이유를 알고 있지만, 각 스레드에 일종의 매개 변수를 전달한 다음 스레드가 부분 쿼리를 수행하도록하는 것이 최선입니다. 이렇게하면 스레드가 호출 코드와 구별됩니다.

높은 DB 쿼리로 인한 지연 시간을 줄이기 위해 스레드를 사용하려는 경우 트랜잭션 관리를 사용하면 더 나은 경로를 찾을 수 있습니다. 이 링크 link에는 유용한 팁이 있습니다. 스레드 대신이 코드를 사용합니다.

관련 문제