개요
이전 글에서 SQLAlchemy를 사용해 테이블 생성과 데이터 삽입, 갱신, 삭제 등의 기본적인 데이터베이스 작업을 수행하는 방법을 알아보았다.
이번 글에서는 UPSERT를 구현하는 방법을 알아보려고 한다. UPSERT의 경우에는 데이터베이스 엔진마다 쿼리문이 조금씩 다른데 이 글에서는 MySQL을 기준으로 적어두려고 한다.
Dialects
dialect란 SQLAlchemy가 다양한 DBAPI를 구현하고 데이터베이스와 통신하는 데 사용하는 시스템이다. 이를 위해서는 적절한 DBAPI 드라이버가 설치되어 있어야 한다.
SQLAlchemy는 PostgreSQL, MySQL, MariaDB, SQLite, Oracle, Microsoft SQL Server에 대한 dialect를 포함하고 있다. 이외의 데이터베이스 엔진은 SQLAlchemy가 아닌 외부에 의해 관리되고 있는 것 같다.
참고로 Mysql은 아래와 같은 DBAPI를 지원하고 있다.
- mysqlclient (maintained fork of MySQL-Python)
- PyMySQL
- MariaDB Connector/Python
- MySQL Connector/Python
- asyncmy
- aiomysql
- CyMySQL
- PyODBC
- Supporte
INSERT ~ ON DUPLICATE KEY UPDATE (Upsert)
dialect를 사용하기 위해서는 적절한 라이브러리 import가 필요하다. MySQL에서 UPSERT는 INSERT 문에 해당되므로 아래와 같은 모듈 임포트가 필요하겠다.
from sqlalchemy.dialects.mysql import insert
그리고 일반적인 INSERT 객체를 만드는 것과 동일하게 INSERT 함수를 호출한다.
from sqlalchemy.dialects.mysql import insert
insert_stmt = insert(user_table).values(
id="some_existing_id", name="inserted value"
)
print(insert_stmt)
on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
name=insert_stmt.inserted.name, fullname="U"
)
print(on_duplicate_key_stmt)
그리고 생성한 Insert 객체의 on_duplicate_key_update() 함수를 호출하면 바로 ON DUPLICATE KEY UPDATE 절을 추가하게 되는 것이다.
ON DUPLICATE KEY UPDATE는 기본 키, 고유 키와 충돌이 발생할 때 데이터 갱신을 시도하며, 갱신하는 값은 키워드 변수로 전달하는 값이 된다. 갱신하는 값은 키워드 매개변수가 아니라 딕셔너리 형태로 전달해도 된다.
on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
{"name": "some data", "fullname": "U"},
)
참고 문서
https://docs.sqlalchemy.org/en/20/dialects/index.html
https://docs.sqlalchemy.org/en/20/dialects/mysql.html
https://docs.sqlalchemy.org/en/20/dialects/mysql.html#insert-on-duplicate-key-update-upsert