ETL 파이프라인을 구현하다 보면,
적재 결과를 로그 테이블에 남기기 위해 SQLAlchemy의 text() 기반 INSERT 구문을 사용하는 경우가 많다.
이때 VALUES(:컬럼명)과 함께 전달하는 딕셔너리 데이터가 실제로 어떻게 DB에 들어가는지 헷갈릴 수 있다.
SQL 구문에서 사용하는 :table_name, :batch_id 같은 표기는
실제 값이 아니라 자리표시자(bind parameter) 이다.
즉, “여기에 나중에 값이 채워질 자리”를 미리 표시해둔 것이다.
insert_sql = text(
"""
INSERT INTO ingest_log (
table_name,
batch_id,
ingest_start_time,
expected_record_count,
ingest_status,
error_message
)
VALUES (
:table_name,
:batch_id,
:ingest_start_time,
:expected_record_count,
:ingest_status,
:error_message
)
"""
)
그리고 conn.execute() 시점에 전달하는 딕셔너리가
이 자리표시자에 이름 기준으로 매핑되어 실제 값으로 치환된다.
with engine.begin() as conn:
conn.execute(
insert_sql,
{
"table_name": table_name,
"batch_id": batch_id,
"ingest_start_time": ingest_start_time,
"expected_record_count": expected_record_count,
"ingest_status": ingest_status,
"error_message": error_message,
},
)
이때 중요한 점은
- 딕셔너리의 key 이름과 SQL의 :파라미터명이 정확히 일치해야 하고
- value는 문자열, 숫자, datetime, None 등 파이썬 객체 그대로 전달해도 된다는 것이다.
SQLAlchemy가 내부에서 타입 변환과 바인딩을 처리해 주기 때문에
SQL과 데이터가 분리된, 안전하고 읽기 쉬운 INSERT 구문을 만들 수 있다.
이 방식은 단순히 편의성을 넘어서
ETL 로그, 메타데이터 적재 같은 운영성 코드에서 사실상 표준에 가깝다.
'파이썬 > 기초 프로그래밍' 카테고리의 다른 글
| SQLAlchemy에서 text()와 fetchone()의 역할 정리 (0) | 2026.02.04 |
|---|---|
| 같은 SQLAlchemy인데 왜 다르게 보일까? to_sql()과 engine.execute()의 역할 차이 (0) | 2026.02.03 |
| 파이썬에서 모듈 전역 변수는 왜 함수 파라미터 없이도 사용할 수 있을까 (0) | 2026.02.03 |
| 데이터 엔지니어링에서 Enum을 활용한 ETL 파이프라인 설계 (0) | 2025.11.28 |
| 파이썬 Descriptor를 활용한 속성 제어 예제 (0) | 2025.09.15 |