Python/공부공부
[Python] SQLAlchemy 업서트(upsert) - PostgreSQL
phyho
2025. 9. 1. 21:02
* 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"} # 충돌 시 업데이트
)