본문 바로가기

Python/공부공부

[Python] SQLAlchemy 업서트(upsert) - PostgreSQL

 

* on_conflict_do_update

from sqlalchemy.dialects.postgresql import insert

ins = insert(user_table).values(id=1, name="Alice")
stmt = ins.on_conflict_do_update(
    index_elements=['id'],          # 충돌 기준 (unique 키/PK)
    set_={"name": "Alice Updated"}  # 충돌 시 업데이트할 값
)

id를 기준으로
 - 데이터가 없는 경우, 새로운 행 insert
 - 데이터가 있는 경우(충돌), 기존 행 name 컬럼 업데이트 

* ins 는 SQLAlchemy Core의 (insert) 쿼리 객체
* stmt 는 UPSERT를 수행할 수 있는 쿼리 객체
  => ins를 확장하여 PostgreSQL 전용의 UPSERT 문법을 붙인 새로운 (insert)객체

 

* on_conflict_do_nothing

ins = insert(user_table).values(id=2, name="Bob")
stmt = ins.on_conflict_do_nothing(index_elements=['id'])

id를 기준으로
 - 데이터가 없는 경우, 새로운 행 insert
 - 데이터가 있는 경우(충돌), 동작X.

 


 

(복합키인 경우)

# 복합키 (id, dept_id) 기준 UPSERT
stmt = insert(user_table).values(
    id=1,
    dept_id=10,
    name="Alice"
).on_conflict_do_update(
    index_elements=["id", "dept_id"],     # 복합키 지정
    set_={"name": "Alice Updated"}       # 충돌 시 name 갱신
)

컬럼명 대신 아래처럼 제약조건 이름으로 지정해도 된다. (대신 DB에 정의된 제약조건 이름과 일치해야함!)

stmt = insert(user_table).values(
    id=1,
    dept_id=10,
    name="Alice"
).on_conflict_do_update(
    constraint="user_unique",            # 제약조건 이름으로 지정
    set_={"name": "Alice Updated"}       # 충돌 시 업데이트
)