sqlite-utils 4.0rc1에 마이그레이션(migrations) 및 중첩 트랜잭션(nested transactions) 추가
요약
Python 라이브러리 및 CLI 도구인 sqlite-utils 4.0rc1이 출시되었습니다. 이번 업데이트에는 데이터베이스 마이그레이션 지원과 중첩 트랜잭션을 위한 db.atomic() 기능이 새롭게 추가되었습니다.
핵심 포인트
- sqlite-migrate 패키지를 포팅한 데이터베이스 마이그레이션 기능 도입
- Python 코드 및 CLI 명령어를 통한 간편한 마이그레이션 실행 가능
- 세이브포인트를 활용한 중첩 트랜잭션(db.atomic) 지원
- 메이저 업데이트로 인한 일부 하위 호환성 변경 사항 주의 필요
sqlite-utils 4.0rc1에 마이그레이션(migrations) 및 중첩 트랜잭션(nested transactions) 추가
2026년 6월 21일
sqlite-utils는 SQLite 데이터베이스 작업을 위한 저의 통합 Python 라이브러리이자 CLI 도구입니다. 이 도구는 Python의 기본 sqlite3 패키지 상단에서 복잡한 테이블 변환(table transformations), JSON 데이터로부터의 자동 테이블 생성(automatic table creation) 등을 포함하여 광범위한 고수준 작업(higher-level operations) 세트를 제공합니다.
sqlite-utils v4의 첫 번째 출시 후보(release candidate)인 sqlite-utils 4.0rc1을 출시했습니다. 메이저 버전 업데이트(major version bump)는 일부 (사소한) 하위 호환되지 않는 변경 사항(backwards incompatible changes)이 있음을 의미하므로, 안정적인 릴리스(stable release)를 확정하기 전에 사람들이 이를 미리 사용해 보기를 바랍니다.
새로운 기능: 마이그레이션(migrations)
이 RC 버전에는 이전 4.0 알파(alphas) 버전과 비교하여 두 가지 중요한 새로운 기능이 있습니다.
첫 번째는 데이터베이스 마이그레이션(database migrations) 지원입니다. 이것은 완전히 새로운 구현은 아닙니다. 몇 년 전에 출시했던 sqlite-migrate 패키지를 약간 수정하여 포팅(port)한 것입니다. 해당 패키지는 시간이 지나면서 그 성능이 입증되었다고 생각하기에, 이제 이를 sqlite-utils에 직접 포함할 준비가 되었습니다.
migrations.py 파일에 작성된 마이그레이션 세트는 다음과 같은 모습입니다:
from sqlite_utils import Database, Migrations
migrations = Migrations("creatures")
@migrations()
def create_table(db):
db["creatures"].create(
{"id": int, "name": str, "species": str},
pk="id",
)
@migrations()
def add_weight(db):
db["creatures"].add_column("weight", float)
이것은 creatures 테이블을 생성하는 마이그레이션 하나와, 해당 테이블에 컬럼을 추가하는 마이그레이션 하나를 포함하여 총 두 개의 마이그레이션 세트를 정의합니다.
그 후 Python을 사용하여 다음과 같이 마이그레이션을 실행할 수 있습니다:
db = Database("creatures.db")
migrations.apply(db)
또는 명령줄(command-line) migrate 명령어를 사용할 수도 있습니다:
sqlite-utils migrate creatures.db migrations.py
이 시스템은 의도적으로 작게 설계되었습니다. 역마이그레이션(reverse migrations)을 제공하지 않으므로, 실수가 발생하면 새로운 마이그레이션을 배포하여 이를 되돌려야 합니다.
이전 버전은 수년 동안 LLM 및 다양한 다른 프로젝트에서 사용되어 왔으므로, 설계가 안정적이고 잘 작동한다고 확신합니다.
새로운 마이그레이션(migrations) 기능은 여기에서 문서화되어 있습니다.
새로운 기능: db.atomic() 트랜잭션 (transactions)
이 기능은 마이그레이션보다 훨씬 적게 사용되므로, 테스터들의 더 많은 주의가 필요합니다.
이전에는 sqlite-utils가 주로 sqlite3 메커니즘을 직접 재사용하는 with db.conn: 구문을 통해 트랜잭션 관리를 사용자에게 맡겼습니다.
SQLite는 세이브포인트 (savepoints) 형태의 중첩 트랜잭션 (nested transactions)을 지원하므로, 이를 최대한 쉽게 사용할 수 있게 해주는 추상화 계층을 만들고 싶었습니다.
저는 Django와 Peewee에서 사용되는 "atomic"이라는 용어를 빌려왔습니다. 새로운 API의 모습은 다음과 같습니다:
with db.atomic(): db.table("dogs").insert({"id": 1, "name": "Cleo"}, pk="id") try: with db.atomic(): db.table("dogs").insert({"id": 2, "name": "Pancakes"}) raise ValueError("skip this one") except ValueError: pass db.table("dogs").insert({"id": 3, "name": "Marnie"})
더 자세한 내용은 문서에서 확인하세요.
하위 호환성이 깨지는 변경 사항 (Backwards incompatible changes)
v4에서의 하위 호환성이 깨지는 변경 사항은 알파(alpha) 릴리스 노트에 설명되어 있습니다. 4.0a0의 경우:
- Upsert 작업은 이제 3.23.1 이후의 모든 SQLite 버전에서 SQLite의
INSERT ... ON CONFLICT SET구문을 사용합니다. 이는 이전의INSERT OR IGNORE이후UPDATE가 이어지는 동작에 의존하는 앱들에게는 매우 미세한 파괴적 변경(breaking change)입니다. (#652)- Python 라이브러리 사용자들은
Database()생성자에use_old_upsert=True를 전달함으로써 이전 구현 방식을 선택적으로 사용할 수 있습니다.INSERT OR IGONE을 사용한 대안적인 upsert 방식을 참조하세요.
- Python 라이브러리 사용자들은
- Python 3.8 지원을 중단하고, Python 3.13 지원을 추가했습니다. (#646)
sqlite-utils tui는 이제sqlite-utils-tui플러그인에 의해 제공됩니다. (#648)- 테스트 스위트(Test suite)는 이제 새로운
INSERT ... ON CONFLICT SET구문이 추가되기 전의 마지막 버전(2018-04-10 기준)인 SQLite 3.23.1에 대해서도 실행됩니다. (#654)
그리고 4.0a1의 경우:
파괴적 변경 사항 (Breaking change): db.table(table_name)
메서드는 이제 테이블에서만 작동합니다. SQL 뷰 (view)에 접근하려면 대신 db.view(view_name)를 사용하세요. (#657)
table.insert_all()및table.upsert_all()메서드에서 이제 딕셔너리 (dictionary) 대신 리스트 (list) 또는 튜플 (tuple)의 이터레이터 (iterator)를 인자로 받을 수 있습니다. 첫 번째 항목은 컬럼 (column) 이름들의 리스트/튜플이어야 합니다. 자세한 내용은 '리스트 또는 튜플 이터레이터에서 데이터 삽입하기'를 참조하세요. (#672)
파괴적 변경 사항 (Breaking change): 기본 부동 소수점 (floating point) 컬럼 타입이 FLOAT에서 부동 소수점 값에 올바른 SQLite 타입인 REAL로 변경되었습니다. 이는 데이터를 삽입할 때 자동 감지되는 컬럼에 영향을 미칩니다. (#645)
-
패키징 (packaging)을 위해
setup.py대신pyproject.toml을 사용합니다. (#675) -
Python API의 테이블은 이제 처음 생성되었을 때의 기본 키 (primary key) 및 기타 스키마 (schema) 상세 정보를 훨씬 더 잘 기억합니다. (#655)
파괴적 변경 사항 (Breaking change): table.convert() 및 sqlite-utils convert 메커니즘은 더 이상 False로 평가되는 값을 건너뛰지 않습니다. 이전에는 --skip-false 옵션이 필요했으나, 이 옵션은 제거되었습니다. (#542)
파괴적 변경 사항 (Breaking change): 이 라이브러리로 생성된 테이블은 이제 스키마에서 테이블 및 컬럼 이름을 `
이에 대해 sqlite-utils Discord 채널에서 함께 이야기를 나누거나, GitHub Issues에 버그를 제보해 주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 RSS: Simon Willison's Weblog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기