
itertools.chain 객체와 lazy iterator는
데이터 처리와 관련하여 중요하며,
효율적인 코드를 작성하는 데 도움이 됨
itertools는 파이썬 표준 라이브러리로,
효율적인 반복을 위한 함수들을 제공
그중 itertools.chain()은 여러 개의 순회 가능한(iterable) 객체
(예: 리스트, 튜플, Django QuerySet 등)를 하나로 연결하여
새로운 iterator를 만드는 함수
Django에서 여러 QuerySet의 결과를 하나로 합쳐서 사용하고 싶을 때
itertools.chain()을 유용하게 사용할 수 있음
예를 들어, 서로 다른 조건으로 필터링된 두 개의 QuerySet을 합쳐서 하나의 목록처럼 다루고 싶을 때 사용
from itertools import chain
from .models import MyModel
queryset1 = MyModel.objects.filter(status='active')
queryset2 = MyModel.objects.filter(is_featured=True)
combined_results = chain(queryset1, queryset2)
# combined_results는 이제 MyModel 객체들을 순회하는 하나의 iterator
for item in combined_results:
print(item.name)
itertools.chain의 장점은 데이터를 바로 메모리에 로드하여
새로운 리스트를 만들지 않고,
요청 시에 데이터를 하나씩 가져온다는 것
특히 다루는 데이터의 양이 많을 때
메모리 효율성을 높이는 데 도움이 됨
하지만 여기서 주의할 점은
itertools.chain()의 결과는 Django의 QuerySet 객체가 아님
단순히 여러 순회 가능한 객체의 요소들을 순서대로 제공하는 iterator일 뿐임
따라서 combined_results 객체에 .filter(), .order_by(), .annotate()와 같은 QuerySet 전용 메서드를 직접 사용할 수 없음
QuerySet 메서드를 사용하려면
chain으로 연결하기 전에 각 QuerySet에 미리 적용하거나,
chain으로 얻은 iterator를 리스트 등으로 변환한 후
파이썬의 기본 리스트/iterator 처리 방법을 사용해야함
"Lazy Evaluation"는
연산의 결과 값이 필요할 때까지 계산을 미루는 방식
"Lazy Iterator"는 이러한 지연 평가 방식을 사용하는 iterator를 말함
Django의 QuerySet은 대표적인 Lazy Evaluation의 예시임
MyModel.objects.filter(status='active').order_by('name')
와 같이 QuerySet을 정의하더라도,
이 시점에는 실제로 데이터베이스 쿼리가 실행되지 않음
# 이 시점에는 데이터베이스 쿼리가 실행되지 않음
active_users = User.objects.filter(is_active=True)
print("QuerySet이 정의되었음")
# 데이터를 순회하거나, 리스트로 변환하거나, 특정 메서드(len(), count() 등)를 호출할 때 쿼리가 실행됨
for user in active_users: # 이 순간 데이터베이스 쿼리가 실행됨
print(user.username)
print("데이터 순회가 끝났음")
필요한 데이터만 그때그때 가져오므로
메모리를 효율적으로 사용할 수 있음
모든 데이터를 미리 메모리에 로드할 필요가 없음
여러 .filter(), .exclude(), .order_by() 등을 연결하여 복잡한 쿼리를 구성할 수 있음
Django ORM은
마지막에 최종적으로 필요한 데이터만 가져오기 위한
하나의 효율적인 SQL 쿼리를 생성하여 실행함
itertools.chain 역시
여러 순회 가능한 객체를 합쳐 하나의 iterator를 반환하며,
이 iterator 또한 Lazy하게 작동함
즉, chain으로 연결된 객체들을 순회할 때
실제로 데이터가 필요할 때
각 객체로부터 값을 가져오는 방식임
Django QuerySet은 데이터베이스와의 상호작용을 Lazy하게 처리하여 효율성을 높이는 객체이며,
itertools.chain은 파이썬의 일반적인 Lazy Iterator로
여러 순회 가능한 객체를 하나처럼 다룰 수 있게 해주는 도구itertools.chain은 Django QuerySet을 포함한 다양한 순회 가능한 객체와 함께 사용될 수 있지만,
chain 결과 자체는 QuerySet이 아니므로
QuerySet의 특별한 기능들은 사용할 수 없다는 점을 기억할 것