이번 챕터에서는 SQLAlchemy Core 방식으로 데이터를 INSERT 하는 방법을 배웁니다.
먼저 다음처럼 INSERT 구문을 만들 수 있습니다.
>>> from sqlalchemy import insert
# stmt는 Insert 객체 인스턴스입니다.
>>> stmt = insert(user_table).values(name='spongebob', fullname="Spongebob Squarepants")
>>> print(stmt)
'INSERT INTO user_account (name, fullname) VALUES (:name, :fullname)'
여기서
user_table
은 우리가 이전 챕터에서 만든Table
객체입니다. 우리는 아래처럼 만들었었습니다.from sqlalchemy import MetaData from sqlalchemy import Table, Column, Integer, String metadata = MetaData() user_table = Table( 'user_account', metadata, Column('id', Integer, primary_key=True), Column('name', String(30)), Column('fullname', String), )
stmt
를 보면 아직 매개변수가 매핑되지는 않았습니다.
이는 다음처럼 complie()
한 후에 확인할 수 있습니다.
>>> compiled = stmt.compile()
>>> print(compiled.params)
{'name': 'spongebob', 'fullname': 'Spongebob Squarepants'}
이제 위에서 만든 INSERT 구문을 Core 방식으로 실행해봅시다.
>>> with engine.connect() as conn:
... result = conn.execute(stmt)
... conn.commit()
# 위 코드는 결과적으로 아래 쿼리를 실행합니다.
BEGIN (implicit)
INSERT INTO user_account (name, fullname) VALUES (?, ?)
[...] ('spongebob', 'Spongebob Squarepants')
COMMIT
conn.execute(stmt)
의 반환 값을 받은 result
에는 어떤 정보가 있을까요?
result
는 CursorResult
객체입니다.
여기에는 실행 결과물에 대한 여러 정보를 담고있는데, 특히 데이터 행을 담고있는 Row
객체를 들고있습니다.
우리는 방금 데이터를 삽입했고, 이에 대한 결과물로 다음처럼 삽입된 데이터의 기본 키 값을 확인할 수 있습니다.
>>> result.inserted_primary_key # 이 역시 Row 객체입니다.
(1, ) # 기본 키가 여러 열로 구성될 수 있으므로 튜플로 표현됩니다.
위에서는 다음처럼 insert
에 values
까지 함께 포함하여 구문울 만들었습니다.
>>> stmt = insert(user_table).values(name='spongebob', fullname="Spongebob Squarepants")
하지만 이 방법 외에도 다음처럼 Connection.execute()
메서드에 매개변수를 전달하여 INSERT 구문을 실행할 수 있습니다.
공식문서에는 이게 좀 더 일반적인 방법이라고 말합니다.
>>> with engine.connect() as conn:
... result = conn.execute(
... insert(user_table),
... [
... {"name": "sandy", "fullname": "Sandy Cheeks"},
... {"name": "patrick", "fullname": "Patrick Star"}
... ]
... )
... conn.commit()
공식문서에는 하위 쿼리까지 포함하여 실행시키는 법을 별도의 블락에서 설명하고 있는데, 튜토리얼 내용으로는 다소 적합하지 않다고 판단하여 이 글에는 포함하지 않았습니다. 이 내용이 궁금하신 분들은 원문 링크를 참고하세요.
다음처럼 SELECT 하여 받은 행들을 INSERT 하기 위한 쿼리가 필요한 경우가 있습니다.
이런 사례는 예를 들면 다음 코드처럼 작성할 수 있습니다.
>>> select_stmt = select(user_table.c.id, user_table.c.name + "@aol.com")
>>> insert_stmt = insert(address_table).from_select(
... ["user_id", "email_address"], select_stmt
... )
>>> print(insert_stmt)
"""
INSERT INTO address (user_id, email_address)
SELECT user_account.id, user_account.name || :name_1 AS anon_1
FROM user_account
"""
데이터베이스에서 쿼리 처리 후에 처리된 행의 값을 반환받아야 하는 경우가 있습니다. 이를 RETURNING
문법이라 합니다.
이에 대한 소개 글은 이 블로그 글을 읽어보시면 좋을거 같습니다.
SQLAlchemy Core에서는 이런 RETURNING
문법을 다음처럼 작성할 수 있습니다.
>>> insert_stmt = insert(address_table).returning(address_table.c.id, address_table.c.email_address)
>>> print(insert_stmt)
"""
INSERT INTO address (id, user_id, email_address)
VALUES (:id, :user_id, :email_address)
RETURNING address.id, address.email_address
"""