Django에서 대용량 데이터 처리하기: bulk_create 메서드 활용하기

2024. 1. 16. 22:07개발/Django

728x90
반응형

데이터베이스에 1000개 이상의 Row를 insert 해야하는 상황이 발생할 때, Django의 create나 update_or_create 등을 사용해서 데이터를 저장하면 시간이 상당히 걸릴 수 있습니다. 이러한 방법은 많은 수의 DB 쿼리를 발생시켜 데이터베이스에 과부하를 줄 수 있으며, 이로 인해 서버에 장애가 발생할 수도 있습니다.

 

대용량 데이터를 처리할 때, DB에 보내는 쿼리 수를 줄이는 것만으로도 속도 개선을 크게 시킬 수 있습니다. Django에서는 이를 위해 bulk_create 메서드를 제공합니다.

 

예를 들어, 아래의 코드는 1000번의 쿼리를 실행하여 1000개의 객체를 생성합니다:

for i in range(1000):
    new_object = MyModel.objects.create(name=f'New Example {i}', value=i)

반면에, bulk_create를 사용하면 1번의 쿼리로 1000개의 객체를 생성할 수 있습니다:

# 여러 객체 생성 및 한 번에 저장
objects_to_create = [
    MyModel(name=f'Example{i}', value=i) for i in range(1, 1001)
]

MyModel.objects.bulk_create(objects_to_create)

bulk_create는 또한 batch_size 파라미터를 통해 한 번에 생성할 객체의 수를 지정할 수 있어, 대용량 데이터를 처리하는 데 유용합니다.

 

그러나 bulk_create를 사용할 때 주의해야 할 점은 다음과 같습니다:

bulk_create는 객체의 save 메서드를 호출하지 않기 때문에, 시그널(signal)이나 자동으로 생성되는 필드들

(예: auto_now_add, auto_now)이 자동으로 갱신되지 않습니다. 이를 고려하여 수동으로 설정해야 할 수 있습니다.

 

bulk_create는 기본적으로 객체를 생성하고 바로 데이터베이스에 저장하므로, 생성되는 객체에 대한 validation, signal, custom save 메서드 등이 무시됩니다. 이러한 기능이 필요한 경우 수동으로 처리해야 합니다.

 

Django 3.2 이상에서는 bulk_create에 update_conflicts=True를 설정하면, 생성하려는 객체가 이미 데이터베이스에 존재하는 경우 해당 객체를 업데이트하도록 할 수 있습니다:

# Person 객체 리스트 생성
people = [
    Person(name='John Doe', age=30),
    Person(name='Jane Doe', age=25),
    # ...
]

# bulk_create를 사용하여 객체 생성 또는 업데이트
Person.objects.bulk_create(people, update_conflicts=True, unique_fields=['name'])

위 예시에서, Person 객체는 name 필드를 기준으로 고유성을 확인합니다. 따라서 name이 동일한 객체가 데이터베이스에 이미 존재하는 경우, 해당 객체의 age 필드는 새로운 값으로 업데이트됩니다.

 

이러한 방법을 통해, Django를 활용하여 대용량 데이터를 효율적으로 처리하는 방법을 배웠습니다. 이 기능은 Django 3.2 이상에서 작동하며, 일부 데이터베이스 백엔드에서는 지원되지 않을 수 있습니다. 이를 참고하여 적절히 활용해보시기 바랍니다.