본문 바로가기

소프트웨어 이야기/장고와 루비온레일즈

(Django) Association Table Multiple Filter Chaining 주의사항

관계 테이블에 동일한 레벨로 여러 검색 조건을 걸어야하는 경우, 같은 관계 테이블 컬럼은 모두 같은 필터 안에 조건문을 선언해야합니다.

동일한 관계 테이블을 여러 필터에서 나눠 조회하는 경우, 2가지 문제가 발생하게 됩니다.

1. 쿼리가 기대한 대로 동작하지 않습니다.
2. 중복 테이블 조인이 발생하게 됩니다. 
( T3, T4, T5 같은 테이블 알리아스가 난무하게 됩니다.  😱)

장고는 하나의 필터를 하나의 조건 세트로 인지합니다.

그래서 메서드 체이닝으로 호출된 필터를 각각 다른 조건으로 보고, 별도의 검색조건 쿼리를 만들어냅니다. 

 

메인 테이블에 속한 컬럼에 조건을 거는 경우에는 이런 문제가 발생하지 않아요. 괜찮습니다. 

 

글로 설명하려니 굉장히 복잡하네요. 문제가 되는 샘플 케이스를 보면 이해가 되실거에요.

 

샘플 케이스

관계가 맺어져있는 테이블에 Filter Chaning을 사용했을 때, 실수할 수 있는 케이스는 다음과 같습니다. 

 

아래의 두 쿼리셋이 동일한 쿼리를 호출할 것 같지만, 두 쿼리셋은 각기 다른 의미를 내포하고 있습니다.

Blog.objects.filter(entry__headline__contains='장고', entry__pub_date__year=2019)

 "블로그 글 제목에 '장고'가 포함되어 있고, 2019년도에 생성된 블로그"를 반환합니다. 

Blog.objects.filter(entry__headline__contains='장고').filter(entry__pub_date__year=2019)

"블로그 글 제목에 '장고'가 포함되어 있거나, 2019년도에 생성된 블로그"를 반환합니다.

 

그래서 위와 같은 데이터를 조회하는 경우 첫번째 쿼리는 1개의 블로그만 리턴합니다.

반면 두번째 쿼리는 3개의 블로그를 리턴하게 됩니다.

 

참고 

https://docs.djangoproject.com/en/2.2/topics/db/queries/#spanning-multi-valued-relationships

 

Making queries | Django documentation | Django

Django The web framework for perfectionists with deadlines.

docs.djangoproject.com

https://stackoverflow.com/questions/8164675/chaining-multiple-filter-in-django-is-this-a-bug/8164920#8164920

 

Chaining multiple filter() in Django, is this a bug?

I always assumed that chaining multiple filter() calls in Django was always the same as collecting them in a single call. # Equivalent Model.objects.filter(foo=1).filter(bar=2) Model.objects.filte...

stackoverflow.com