Django에서 모델 객체 대량 생성


91

데이터베이스에 저장할 개체가 많으므로이를 사용하여 Model 인스턴스를 만들고 싶습니다.

django를 사용하면으로 모든 모델 인스턴스를 생성 MyModel(data)한 다음 모두 저장하고 싶습니다.

현재 다음과 같은 것이 있습니다.

for item in items:
    object = MyModel(name=item.name)
    object.save()

객체 목록을 직접 저장할 수 있는지 궁금합니다. 예 :

objects = []
for item in items:
    objects.append(MyModel(name=item.name))
objects.save_all()

하나의 트랜잭션에 모든 개체를 저장하는 방법은 무엇입니까?


이 공은이에 대한 수정을 구현하는 롤링 것 같다 code.djangoproject.com/ticket/19527
DANH

1
list.save_all 궁금하십니까? 궁금해하는 것을 의역하고 주제 질문에서 첫 번째 단어 2 개를 사용하여 거의 스스로 대답 할 수 있습니다.
Sławomir Lenart

답변:


97

django 개발 당시에 bulk_create는 클래스 생성자를 사용하여 생성 된 객체 배열을 입력으로받는 객체 관리자 메서드 가 존재합니다 . 장고 문서 확인



1
그러나 bulk_create에는 save ()가 자동으로 수행하는 AutoField 인 경우 기본 키를 생성하지 않는 것과 같은 몇 가지 제한 사항이 있습니다.
Hitesh Garg

@HiteshGarg, 지금도 여전히 사실입니까?
Raydel Miranda

1
@RaydelMiranda, 네, 여전히 사실입니다. 문서에 바로 있습니다.If the model’s primary key is an AutoField it does not retrieve and set the primary key attribute, as save() does, unless the database backend supports it (currently only PostgreSQL).
interDist

1
사용 장고 3.0.x 버전을 내가 사용하는 것이 확인 bulk_create()어떤 신호를 트리거하지 않습니다. 이유가 궁금합니다.
enchance

43

사용 bulk_create()방법. 이제 Django의 표준입니다.

예:

Entry.objects.bulk_create([
    Entry(headline="Django 1.0 Released"),
    Entry(headline="Django 1.1 Announced"),
    Entry(headline="Breaking: Django is awesome")
])

1
Django 1.10에서 변경 : PostgreSQL을 사용할 때 bulk_create ()를 사용하여 생성 된 객체에 대한 기본 키 설정 지원이 추가되었습니다.
elad silver

4

루프 (postgres 9.1)에 대해 수동 트랜잭션 처리를 사용하도록 저를 위해 일했습니다.

from django.db import transaction
with transaction.commit_on_success():
    for item in items:
        MyModel.objects.create(name=item.name)

실제로 '네이티브'데이터베이스 대량 삽입과 동일하지는 않지만 전송 / ORMS 작업 / SQL 쿼리 분석 비용을 피 / 감소시킬 수 있습니다.


1
이것은 약간 변경되었습니다. 이제 거래는 commit_on_success더 이상 없습니다. 당신은 사용해야합니다 transaction.atomic(): 참조 stackoverflow.com/questions/21861207/...을
t_io

4

다음은 인용 해제 및 이스케이프 해제 루틴을 모두 제외하고 열로 구분 된 파일에서 항목을 대량으로 만드는 방법입니다.

SomeModel(Model):
    @classmethod
    def from_file(model, file_obj, headers, delimiter):
        model.objects.bulk_create([
            model(**dict(zip(headers, line.split(delimiter))))
            for line in file_obj],
            batch_size=None)

3

한 줄 구현의 경우지도에서 람다 식을 사용할 수 있습니다.

map(lambda x:MyModel.objects.get_or_create(name=x), items)

여기서 람다는 항목 목록의 각 항목을 x에 일치시키고 필요한 경우 데이터베이스 레코드를 만듭니다.

Lambda 문서


당신은 아마이 언급 할 lambda수있다 map이상의 PED items:map(lambda name: MyModel.objects.get_or_create(name = name), items)
마노 Govindan

Ja, 그게 내가 말하려는 또 다른 방법입니다 (:
FallenAngel

2

create를 사용하면 새 항목 당 하나의 쿼리가 발생합니다. INSERT 쿼리의 수를 줄이려면 다른 것을 사용해야합니다.

스 니펫이 꽤 오래되었지만 대량 삽입 스 니펫을 사용하여 약간의 성공을 거두었습니다. 다시 작동하려면 몇 가지 변경이 필요할 수 있습니다.

http://djangosnippets.org/snippets/446/


2

bulkops 모듈 에 대한이 블로그 게시물을 확인하십시오 .

내 django 1.3 앱에서 상당한 속도 향상을 경험했습니다.


-19

가장 쉬운 방법은 create단일 단계로 개체를 만들고 저장하는 Manager 메서드 를 사용하는 것입니다.

for item in items:
    MyModel.objects.create(name=item.name)

+1. 경우 name고유하며 중복 입력이 가능 사용하는 것이 좋습니다 것입니다 get_or_create.
Manoj Govindan

16
이것은 질문에 어떻게 대답합니까? Model.objects.create는 object = MoModel (..) object.save ()와 동일합니다. 그리고 이것은 한 번의 트랜잭션으로 그것을하지 않습니다 ...
automagic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.