[django][ORM]쿼리 하압~! 체!

Hyeseong·2020년 12월 25일
0

django

목록 보기
21/35


가수: 山下やました まりや (야마시타 마리야, Mariya Yamashita)
노래: Plastic Love

일본에서는 예~~~전에 유명했는데요. 한국과 해외에서의 인기는 2010년대 후반 유튜브를 통해 갑작스레 폭발적인 인기를 얻으며 전 세계 팬들로부터 알려진 《Plastic Love》통해 각광을 받았어요~


쿼리 합치기

SQL에서는 두개 이상의 queryset의 result-set을 합칠때 UNION 연산자를 사용합니다~~

여기서 조건이 분기 됩니다.
1. <C모델의 a쿼리셋 + b쿼리셋>
2. <C모델의 a쿼리셋> + <D모델의 F쿼리셋>

1번째 조건은 문제가 없습니다.

하지만!!
문제는 2번째 조건이 다른 모델의 쿼리셋을 합칠수 있냐 없냐 아니겠습니까~?!

다메다요!

기억하세요! 다른 필드 타입인 경우 안된다는거!
charfield면 charfiled! emailfiled면 emailfiled로 딱딱! 맞아 떨어져야 해요.

union()메소드가 마치 더하기처럼 딱! 연결해준거에요.

하지만 union()메소드가 q1의 값을 변경하지는 않아요~ return값을 변수에 할당해줘야 써먹을수 있다는거!

>>> q1 = User.objects.filter(id__gte=5)
>>> q1
<QuerySet [<User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>
>>> q2 = User.objects.filter(id__lte=9)
>>> q2
<QuerySet [<User: admin>, <User: yash>, <User: john>, <User: Ricky>, <User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>]>


>>> q1.union(q2)
<QuerySet [<User: admin>, <User: yash>, <User: john>, <User: Ricky>, <User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>
>>> q2.union(q1)
<QuerySet [<User: admin>, <User: yash>, <User: john>, <User: Ricky>, <User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>


>>> q1
<QuerySet [<User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>, <User: Raghu>, <User: rishab>]>
>>> q2
<QuerySet [<User: admin>, <User: yash>, <User: john>, <User: Ricky>, <User: sharukh>, <User: Ritesh>, <User: Billy>, <User: Radha>, <User: sohan>]>
>>>

오류 발생

>>> q3
<QuerySet [<EventVillain: EventVillain object (1)>]>
>>> q1.union(q3)
django.db.utils.OperationalError: SELECTs to the left and right of UNION do not have the same number of result columns

union() 메서드는 합하려는 쿼리셋의 필드데이터 유형이 서로 일치할 때만 실행할 수 있어요.

Hero 모델과 Villain 모델은 둘 다 name 필드와 gender 필드를 갖고 있습니다. values_list 를 이용해 공통된 필드만 가져온 뒤 union을 수행할 수 있습니다.

Hero.objects.all().values_list(
    "name", "gender"
).union(
Villain.objects.all().values_list(
    "name", "gender"
))

위 코드를 실행하면 Hero 모델과 Villain 모델의 이름과 성별을 구할 수 있습니다.

profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글