Django의 selectrelated 및 prefetchrelated 방법 비교

11484 단어 Django
모델 정의
class Author(models.Model):
    """    """
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    email = models.EmailField()

    class Meta:
        db_table = 'author'


class Book(models.Model):
    """    """
    name = models.CharField(max_length=300)
    pages = models.IntegerField()
    price = models.FloatField()
    rating = models.FloatField()
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)

    class Meta:
        db_table = 'book'


class BookOrder(models.Model):
    """      """
    book = models.ForeignKey("Book", on_delete=models.CASCADE)
    price = models.FloatField()
    create_time = models.DateTimeField(auto_now_add=True, null=True)

    class Meta:
        db_table = 'book_order'

select_related
개발 과정에서 한 테이블의 외부 키가 인용한 테이블의 내용을 자주 사용한다. 예를 들어 아래의 첫 번째 쓰기 방법은 모든 책에 대해 그들의 외부 키가 인용한 테이블 데이터를 단독으로 조회하여 데이터베이스에 여러 번 방문하게 하여 효율이 떨어진다.select_related는 이 문제를 해결하는 데 사용되는 것으로 연합 조회 조작을 한 것과 같다. 조회 후 외부 키가 인용한 표의 데이터를 메모리에 동시에 저장하기 때문에 모두 한 번의 조회 조작만 했다. 아래의 두 번째 문법과 같다.
# 1.    
books = Book.objects.all()
for book in books:
    #                book    author,           SQL  
    print(book.author.name)

# 2.            
books = Book.objects.select_related('author')
for book in books:
	#   select_related            ,            SQL  
    print(book.author.name)

prefetch_related
위의 select_related는 이미'정방향'의 외키 조회를 해결할 수 있지만, 인용된 표, 예를 들어 북표에서 우리가 인용된 북오더 표를 조회할 수 있기를 희망하는 정보는 할 수 없다.이때 prefetch_related를 사용해야 한다. 예를 들어 아래의 문법을 사용한다.
# bookorder_set         BookOrder,         ,     _set        ,  Django       
books = Book.objects.prefetch_related('bookorder_set')
for book in books:
    print('=' * 30)
    print(book.name)
    #      prefetch_related,          bookorder_set            
    orders = book.bookorder_set.all()
    for order in orders:
        print(order.id)
prefetch_related위의 정방향 조회 기능도 실현할 수 있지만 prefetch_relatedselect_related는 크게 다르다. prefetch_related는 사실상 두 가지 조작을 했기 때문이다. 첫 번째 단계는 모든 책을 표에서 꺼낸 다음에 책의 메시지를 통해 두 번째 검색을 해서 책의 정보를 얻는 것이다.따라서 정방향 조회라면 select_related를 더 추천하고 한 번 더 조회할 수 있습니다.
prefetch_related의 조건부 조회
주의해야 할 것은 prefetch_related를 통해 찾아낸 bookorder_set는 재여과를 할 수 없다. 그렇지 않으면 이전의 조회가 효력을 상실하고 진행하지 않은 prefetch_related와 같이 모든 순환에 대해 SQL 문장을 단독으로 집행할 수 있기 때문에 이런 경우 다음 글쓰기를 사용해야 한다.
#       :        90   
from django.db.models import Prefetch
#  Prefetch queryset        ,      
prefetch = Prefetch('bookorder_set', queryset=BookOrder.objects.filter(price__gte=90))
books = Book.objects.prefetch_related(prefetch)
for book in books:
    print('=' * 30)
    print(book.name)
    orders = book.bookorder_set.all()
    for order in orders:
        print(order.id)

좋은 웹페이지 즐겨찾기