반응형
QLAlchemy는 Python에서 데이터베이스와 상호작용하기 위한 강력한 ORM(Object Relational Mapping) 및 Core API를 제공합니다. 특히, 대량 데이터를 삽입할 때는 성능과 효율성이 중요한데, 이를 위한 대표적인 두 가지 방법이 있습니다:
- sqlalchemy.orm.bulk_insert_mappings
- connection.execute(target_table.insert(), insert_data)
이번 글에서는 이 두 방법의 차이점과 성능을 비교하고, 각각의 사용 사례와 최적의 활용 방안을 알아보겠습니다.
bulk_insert_mappings와 connection.execute 개요
특징 | bulk_insert_mappings | connection.execute(target_table.insert()) |
레벨 | ORM (객체 관계 매핑) | Core (저수준 SQL 실행) |
사용 방법 | ORM 매핑된 클래스와 데이터 사용 | Core 테이블 객체와 데이터 사용 |
속도 | 상대적으로 빠름 (ORM 세션에서 최적화된 방식으로 일괄 삽입) | 상대적으로 느림 (하나씩 매핑하여 실행) |
트랜잭션 관리 | ORM 세션이 관리 | engine.begin()에서 수동 관리 가능 |
데이터 확인 및 검증 | ORM 매핑된 객체의 검증 및 추가 작업 가능 | 데이터는 그대로 전달되며 검증은 직접 처리 |
메모리 효율성 | 대규모 데이터 처리 시 상대적으로 효율적 | 데이터 크기에 따라 메모리 소비 증가 |
1. bulk_insert_mappings
bulk_insert_mappings는 SQLAlchemy ORM에서 제공하는 대량 데이터 삽입을 위한 고성능 메서드입니다. Python 딕셔너리와 ORM 매핑된 클래스를 사용해 데이터를 삽입하며, ORM 유효성 검사를 지원합니다.
장점
- 한 번의 호출로 다수의 데이터를 삽입.
- ORM 기반의 데이터 유효성 검증 가능.
- 대량 데이터 삽입 시 빠른 속도와 메모리 효율성을 제공.
- ORM 메타데이터 활용 가능.
단점
- ORM 매핑된 클래스가 필요하여 간단한 작업에는 설정이 과도할 수 있음.
- 데이터베이스의 하위 레벨에서 작업이 필요한 경우 유연성이 떨어짐.
사용법
from sqlalchemy.orm import Session
# 데이터 예시
data_to_insert = [
{"column1": "value1", "column2": "value2"},
{"column1": "value3", "column2": "value4"}
]
# ORM 세션 생성
with Session(engine) as session:
session.bulk_insert_mappings(MyORMClass, data_to_insert)
session.commit()
2. connection.execute
connection.execute는 SQLAlchemy Core API를 사용하여 SQL문을 직접 실행하는 방식입니다. 이 방법은 ORM을 사용하지 않고, 테이블 객체와 데이터를 직접 전달하여 작업을 수행합니다.
장점
- ORM에 의존하지 않으므로 간단한 데이터 삽입 작업에 적합.
- Core API를 사용해 SQL문을 세밀히 제어 가능.
- ORM 매핑이 필요 없는 환경에서도 사용 가능.
단점
- 데이터 유효성 검사를 제공하지 않음.
- 대량 데이터 처리 시 성능이 떨어질 수 있음.
- 트랜잭션 관리를 명시적으로 처리해야 함.
사용법
from sqlalchemy import insert
# 데이터 예시
insert_data = [
{"column1": "value1", "column2": "value2"},
{"column1": "value3", "column2": "value4"}
]
# 트랜잭션 실행
with engine.begin() as connection:
connection.execute(target_table.insert(), insert_data)
3. 성능 비교
벤치마크 테스트
- 데이터 삽입량: 10만 건 기준.
- 테스트 환경: PostgreSQL 13, SQLAlchemy 최신 버전.
방법 | 소요 시간 | 설명 |
bulk_insert_mappings | 약 1~2초 소요 | 내부적으로 최적화된 일괄 삽입 방식. |
connection.execute | 약 5~7초 소요 | 데이터 크기에 따라 성능 저하 발생. |
대량 데이터 처리 성능
- bulk_insert_mappings: 대량 데이터 처리에 최적화되어 있어 삽입 속도가 빠르고, 메모리 효율적입니다.
- connection.execute: 데이터가 적은 경우 간단한 삽입 작업에 적합하지만, 대량 데이터에서는 성능이 저하될 수 있습니다.
4. 사용 사례 비교
bulk_insert_mappings 사용에 적합한 경우
- ORM을 사용하는 프로젝트에서 대량 데이터 삽입이 필요한 경우.
- 데이터 유효성 검사를 ORM 레벨에서 수행하고자 할 때.
- 다수의 ORM 매핑된 객체를 한 번에 삽입하고자 할 때.
connection.execute 사용에 적합한 경우
- 간단한 삽입 작업에 적합.
- 데이터 크기가 작고, ORM 설정이 불필요한 환경.
- Core API로 SQL 제어가 필요한 경우.
5. 효율적인 대량 데이터 삽입 전략
데이터를 청크 단위로 처리
대량 데이터 처리 시, 데이터베이스의 제한이나 메모리 부족 문제를 방지하기 위해 데이터를 청크 단위로 삽입합니다.
코드 예시
CHUNK_SIZE = 1000 # 한 번에 처리할 데이터 크기
for i in range(0, len(data_to_insert), CHUNK_SIZE):
chunk = data_to_insert[i:i + CHUNK_SIZE]
with engine.begin() as connection:
connection.execute(target_table.insert(), chunk)
결론
기준 | bulk_insert_mappings | connection.execute |
대량 데이터 처리 | 효율적 | 느림 (데이터 크기에 따라 성능 저하) |
데이터 유효성 | ORM 유효성 검사 제공 | 직접 검증 필요 |
유연성 | ORM 매핑된 클래스 필요 | SQL 제어 가능 |
사용 사례 | 대량 데이터 삽입, ORM 프로젝트에 적합 | 간단한 삽입, Core SQL 작업에 적합 |
- **bulk_insert_mappings**는 ORM을 사용하는 대규모 프로젝트에서 대량 데이터를 삽입할 때 가장 적합한 방법입니다.
- **connection.execute**는 단순하고 유연한 SQL 삽입 작업에 적합하며, 소규모 데이터 처리에 효율적입니다.
728x90
반응형
'개발라이프' 카테고리의 다른 글
Jupyter Notebook에서 ModuleNotFoundError 해결 방법 (1) | 2024.12.20 |
---|---|
bfloat16 (Brain Floating Point 16-bit) (1) | 2024.12.20 |
머신러닝에서 데이터 라벨링이란? (0) | 2024.12.18 |
수학에서 자주 사용하는 기호와 뜻: 완벽 정리 (0) | 2024.12.16 |
Keras 모델 정의 시 경고 메시지 해결 방법: keras.Input() 사용법 (0) | 2024.12.10 |