Django - select_related, prefetch_related

KDG·2020년 7월 4일
0

django를 이용해 데이터베이스 안에있는 데이터를 가져오는 로직을 구현하고, 그 로직을 실행시킬때마다 데이터베이스에 들어가서 데이터를 가져온다. 실행시킬때마다 데이터베이스에 들어가 정보를 가져오면 시간적으로 비효율적일것이다.

데이터 베이스에 정보를 요청하는 것을 Query라고 부른다. 로직을 실행시킬때마다 Query를 줄이기 위해 사용하는 코드가 select_related, prefetch_related다.

1. select_related

  • 정참조 관계에서 사용
  • 쿼리 한번만 수행되고 데이터는 캐쉬되어 다음번에 가져올 때 db쿼리 안함
drink_all=Drink.objects.select_related('category').all()

for drink in drink_all:
    print(drink.category.name)
    
=> 
콜드 브루 커피 —> drink.category.name 을 가져오기 위하여 SELECT 와 같은 SQL 쿼리 하지 않음 이것이 database hit를 안한다는 의미
콜드 브루 커피
콜드 브루 커피
콜드 브루 커피
콜드 브루 커피
브루드 커피
브루드 커피
에스프레소

2. prefetch_related

  • Many to one 또는 Many to Many, 역참조 관계에서 사용
  • 역으로 참조할 때 클래스이름(대문자를 다 소문자로)_set을 붙인다.
  • select_related 처럼 쿼리 한번만 하고 다음번엔 쿼리 안함
drink_data = [ {'drink_name' : drink.name } for drink in list(prefetch_drink.drink_set.all())]
drink_data

=> [{'drink_name': '나이트로 바닐라 크림'}, {'drink_name': '제주 비자림 콜드 브루'}, {'drink_name': '코코넛 화이트 콜드 브루'}, {'drink_name': '나이트로 쇼콜라 클라우드'}, {'drink_name': '콜드 브루 몰트'}]
  • 테이블끼리 복잡하게 포린키로 연결되어있을 때 __을 사용하면 중간테이블을 하나하나 적지않아도 짧은 코드로 연결지을 수 있다.
product_list = ProductColor.objects.prefetch_related('product__menu_category_sub_category__menu_category__menu')

 # ProductColor테이블에서 시작해 menu테이블까지 연결

** related_name

  • 역으로 참조할때 클래스이름_set으로 안하고 .related_name을 설정해주면 클래스이름_set 대신 설정한 이름으로 적을수있다.

  • 중간 테이블이 두개 일 때 필수는 아니지만 되도록이면 related_name을 사용하는 것이 좋다.

  • 이름 설정은 자신의 입장에서 불러올 것을 어떻게 부를 지 설정

0개의 댓글