대량 데이터를 insert, update할 때 sqlalchemy에서 제공하는 add, add_all 등을 사용하는 것보다 빠른 방법이 있다
ORM은 기본적으로 고성능 bulk insert용이 아니다. 이것이 sqlalchemy가 core
기능을 제공하는 이유다
객체 리스트를 대량 저장한다
객체 타입이 다르면 타입별 그룹으로 나뉘기 때문에 객체 리스트의 원소가 동일 타입이면 좋다
s = Session()
objects = [
User(name="u1"),
User(name="u2"),
User(name="u3")
]
s.bulk_save_objects(objects)
bulk_save_objects()
는 메서드명처럼 객체를 대량 저장한다. 이것과 다르게 bulk_insert_mappings()
, bulk_update_mappings()
는 dict list를 받는다. 개인적으로 메서드명이 bulk_insert_mappings
가 아니라 bulk_insert_dicts
였으면 더 좋았을 것 같다.
s.bulk_insert_mappings(User,
[dict(name="u1"), dict(name="u2"), dict(name="u3")]
)
s.bulk_update_mappings(User,
[dict(name="u1"), dict(name="u2"), dict(name="u3")]
)
engine.execute(
Customer.__table__.insert(),
[{"name": 'NAME ' + str(i)} for i in xrange(n)]
)
sqlalchemy core 를 사용하는 게 빠르다
bulk_insert_mappings()
가 model 객체 생성 후 attribute에 값 할당해서 commit하는 것보다 10배 이상 빠르다
그러므로 add_all()
보다 bulk_xxx_xxx()
메서드를 사용하는 게 효율적이다
add_all()은 내부적으로 for문 사용하므로 느리다
속도 빠른 순
core
> bulk_insert_mappings
> bulk_save_objects
> add_all
bulk 연산은 성능 이득을 위해 session 에서 하는 동작을 생략한다. 기본적으로 PK같은 default 값을 넣지 않는다.
bulk_insert_mappings 결과를 받아보고 싶으면 어떻게 해야할까요?