2016-12-07 5 views
0

page_number 특성을 가진 Page 개체를 포함하는 QuerySet이 있습니다. QuerySet은 page_number으로 정렬되므로 [i.page_number for i in pages_query_set]을 실행하면 [1,2,3,5,6,10,11,13,16,19,21]과 같은 결과가 반환됩니다. 내 작업은 Page 개체를 연속적으로 움직이게하는 방법을 작성하는 것입니다.이 예에서 5는 4, 6은 5, 10은 6, 11은 7, 13은 8 등입니다. .Django의 이전 값을 기반으로 빠른 데이터베이스 업데이트

이 내 초기 솔루션, PageQuerySet 클래스 내부 방법 :

def validatePageNumbers(self): 
    prev_page = 0 
    for page in self: 
     if page.page_number > prev_page+1: 
      page.page_number = prev_page+1 
      page.save() 
     prev_page = page.page_number 

기능적으로, 그것은 잘 작동합니다. 하지만 save()을 호출 할 때마다 매번 데이터베이스 쿼리를 호출 할 때마다 속도가 느려집니다. 나는 더 빠른 접근법을 찾아야한다. 이 시퀀스에 단 하나의 "갭"이 있었다면, 단 하나의 update()이 여러 개의 save()보다 훨씬 빠르기 때문에 QuerySet을 슬라이스하고 sliced_qs.update(page_number=models.F('page_number')-gap)과 같은 것을 사용할 것입니다. 그러나 갭은 여러 개이며 꽤 무작위입니다.

그래서 혼란스러워. F 개체가 이러한 루핑을 지원하지 않는 것 같습니다. update()에서 호출 가능 코드를 사용할 수 있다면 좋겠지 만 문서에있는 정보를 찾지 못했고 시도 할 때 작동하지 않습니다. 여기 update()을 적용 할 수있는 방법이 있습니까? 아니면이 방법을 더 빨리 만들 수있는 다른 방법이 있을까요?

답변

0

이 문제와 수많은 병목 현상에 대한 해결책은 매우 간단합니다.

from django.db import transaction 

with transaction.atomic(): 
    #do stuff here 

모든 트랜잭션을 하나의 트랜잭션으로 래핑하고 데이터베이스에 한 번만 도달합니다. This answer 여기에 많은 도움이되었습니다.