파이썬/기초 프로그래밍

SQLAlchemy INSERT 구문에서 values 딕셔너리는 어떻게 매핑될까

Data Jun 2026. 2. 3. 13:30

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 로그, 메타데이터 적재 같은 운영성 코드에서 사실상 표준에 가깝다.