sqlite-utils 4.0rc1 adds migrations and nested transactions
SQLite 작업을 단순화해 주는 sqlite-utils의 4.0rc1 버전이 릴리스되었습니다. 이번 버전에는 대폭 강화된 데이터베이스 마이그레이션 기능과 중첩 트랜잭션을 간편하게 다룰 수 있는 db.atomic()
SQLite 작업을 단순화해 주는 sqlite-utils의 4.0rc1 버전이 릴리스되었습니다. 이번 버전에는 대폭 강화된 데이터베이스 마이그레이션 기능과 중첩 트랜잭션을 간편하게 다룰 수 있는 db.atomic() API가 새롭게 추가되었어요.
sqlite-utils 4.0rc1 출시! 무엇이 달라졌을까요?
sqlite-utils는 파이썬(Python) 라이브러리와 CLI 도구를 하나로 합친 SQLite 유틸리티 모음집이에요. 파이썬의 기본 sqlite3 패키지 위에서 복잡한 테이블 변환, JSON 데이터로부터의 자동 테이블 생성 등 더 고차원의 풍부한 기능들을 제공해 줍니다.
이번에 첫 번째 릴리스 후보(Release Candidate) 버전인 sqlite-utils 4.0rc1이 공개되었는데요. 메이저 버전 숫자가 올라간 만큼 하위 호환성이 깨지는 변경 사항이 포함되어 있어서, 정식 출시 전에 많은 개발자분들이 직접 테스트해 보시길 권장하고 있답니다.
이번 RC 버전에서 가장 돋보이는 두 가지 핵심 신기능을 소개해 드릴게요!
새로운 기능 1: 마이그레이션(Migrations) 지원
첫 번째 주요 신기능은 바로 데이터베이스 마이그레이션 기능이에요. 완전히 새로 개발된 것은 아니고, 저자가 몇 년 전에 출시했던 sqlite-migrate 패키지를 약간 수정해서 이식한 것이랍니다. 오랜 기간 사용되며 안정성이 충분히 검증되었다고 판단하여 이번에 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 테이블을 생성하고, 여기에 weight 컬럼을 추가하는 두 단계의 마이그레이션을 정의하고 있어요.
이렇게 정의한 마이그레이션은 파이썬 코드로 실행할 수 있어요.
db = Database ( "creatures.db" )
migrations . apply ( db )또는 CLI 명령어로도 아주 간단하게 실행할 수 있답니다.
sqlite-utils migrate creatures.db migrations.py이 마이그레이션 시스템은 의도적으로 단순하게 설계되었습니다. 롤백(Reverse Migration) 기능을 제공하지 않기 때문에, 실수가 있다면 롤백하는 대신 실수를 바로잡는 새로운 마이그레이션 코드를 작성해서 적용하는 방식으로 해결해야 해요.
이미 LLM 프로젝트를 비롯해 여러 프로젝트에서 수년간 사용되며 안정성과 유용함이 입증되었으니 안심하고 사용해 보세요!
새로운 기능 2: db.atomic()을 통한 중첩 트랜잭션
이 기능은 마이그레이션에 비해 아직 테스트가 덜 진행된 영역이라 개발자분들의 적극적인 피드백이 필요해요.
이전의 sqlite-utils는 트랜잭션 관리를 전적으로 사용자에게 맡겼고, with db.conn: 구조를 통해 파이썬 sqlite3 엔진의 메커니즘을 직접 활용해야 했어요. 하지만 SQLite는 세이브포인트(Savepoints) 형식의 중첩 트랜잭션을 지원하고 있죠. 이를 더 편리하게 쓸 수 있도록 Django나 Peewee에서 따온 atomic 개념의 추상화 API를 새롭게 도입했습니다.
새로운 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 ( "이 데이터는 건너뜁니다" )
except ValueError :
pass
db . table ( "dogs" ). insert ({ "id" : 3 , "name" : "Marnie" })하위 호환성이 깨지는 변경 사항 (Breaking Changes)
4.0 버전으로 올라오면서 기존 버전과 호환되지 않는 변경점들이 꽤 있습니다. 주로 알파 버전(4.0a0, 4.0a1) 단계에서 정립된 내용들이에요.
| 구분 | 변경 사항 | 상세 내용 |
|---|---|---|
| Upsert 문법 변경 (4.0a0) | SQLite 3.23.1 이상 버전에서 INSERT ... ON CONFLICT SET 구문을 사용합니다. | 기존의 INSERT OR IGNORE 후 UPDATE 방식을 기대하던 앱에는 약간의 동작 차이가 생길 수 있어요. 이전 동작을 원하면 Database(use_old_upsert=True) 옵션을 주면 됩니다. |
| 파이썬 지원 범위 변경 (4.0a0) | Python 3.8 지원을 중단하고, Python 3.13 지원을 추가했습니다. | 최신 환경에 맞춰 파이썬 버전 대응이 변경되었습니다. |
| TUI의 플러그인 분리 (4.0a0) | sqlite-utils tui 명령어가 기본 패키지에서 빠졌습니다. | 대신 sqlite-utils-tui 플러그인을 별도로 설치해서 사용해야 합니다. |
| 테이블과 뷰의 구분 (4.0a1) | db.table(table_name)은 오직 실제 '테이블'에만 동작합니다. | SQL 뷰(View)에 접근할 때는 이제 반드시 db.view(view_name) 메서드를 사용해야 합니다. |
| 기본 실수형 타입 변경 (4.0a1) | 기본 부동 소수점 컬럼 타입이 FLOAT에서 REAL로 변경되었습니다. | 데이터 삽입 시 자동 감지되는 실수형 타입에 SQLite의 올바른 타입 표준인 REAL이 적용됩니다. |
| 값 변환 시 False 처리 (4.0a1) | table.convert()나 sqlite-utils convert 실행 시 False로 평가되는 값을 더 이상 스킵하지 않습니다. | 기존에는 자동 스킵을 방지하기 위해 --skip-false 옵션이 필요했지만, 이제 이 옵션이 제거되었습니다. |
| 식별자 감싸기 규칙 변경 (4.0a1) | 스키마 생성 시 테이블과 컬럼 이름을 큰따옴표(")로 감쌉니다. | 이전에는 대괄호([...])를 사용했으나 표준적인 큰따옴표 방식으로 변경되었습니다. |
| CSV/TSV 타입 감지 기본 활성화 (4.0a1) | CLI로 CSV/TSV 데이터를 가져올 때(insert/upsert) 타입 감지가 기본값으로 설정됩니다. | 예전에는 --detect-types 플래그를 명시해야 타입 감지가 이루어지고 그렇지 않으면 모두 TEXT로 들어갔어요. 이전 동작을 원한다면 새로운 플래그인 --no-detect-types를 사용해야 해요. |
추가적인 마이너 변경 사항
- `table.insert_all()` & `table.upsert_all()` 기능 확장: 딕셔너리 리스트 형태 외에도 리스트나 튜플의 이터레이터를 지원합니다. 단, 첫 번째 항목에는 컬럼 이름의 리스트/튜플을 지정해 주어야 합니다.
- `pyproject.toml` 전환: 패키징 도구로 기존
setup.py대신pyproject.toml을 사용하도록 현대화되었습니다. - 스키마 상태 기억력 개선: Python API에서 테이블 객체가 처음 생성되었을 때의 기본 키(Primary Key)나 스키마 세부 사항을 훨씬 더 안정적으로 기억합니다.
- `--functions` 개선: CLI 환경에서 파이썬 코드 문자열뿐만 아니라 로컬 파이썬 파일의 경로 자체를 전달받을 수 있게 되었고, 이 옵션을 여러 번 사용하는 것도 가능해졌습니다.
🚀 지금 바로 테스트해 보기!
새로운 RC 버전은 다음 명령어로 간단히 설치하여 사용해 볼 수 있습니다.
pip install sqlite-utils==4.0rc1혹은 uv가 설치되어 있다면 설치 과정 없이 일회성으로 CLI 버전을 바로 실행해 볼 수도 있어요.
uvx --with sqlite-utils==4.0rc1 sqlite-utils --help의견이나 버그 제보가 있다면 Discord 채널에 방문하시거나 GitHub Issues를 통해 적극적으로 참여해 주세요!
아직 이 아티클로 만든 공식이 없어요. 첫 번째 공식을 남겨보세요!
나도 공식 만들기
댓글
6댓글을 남기려면 로그인이 필요해요.
이번 4.0 버전은 업서트 동작 방식 변경이나 CSV 임포트 시 타입 감지 기본값 적용 등 기존 운영 환경에 영향을 줄 수 있는 하위 호환성 변경 사항이 많네요. Python 3.8 지원 중단 같은 변화도 포함되어 있는데, 실무에서 이 버전을 안정적으로 업그레이드하기 위해 어떤 검증 절차를 거치는 것이 안전할까요?
이번 4.0 버전은 파이썬 3.8 지원 중단과 더불어 업서트, CSV 타입 감지 등에서 중요한 하위 호환성 변화를 담고 있습니다. 안정적인 전환을 위해 기존 업서트 동작에 의존하는 앱이라면 `use_old_upsert=True` 옵션을 검토하시고, CSV 임포트 시 변경된 기본값 대응을 위해 `--no-detect-types` 플래그가 필요한지 확인하셔야 합니다. 또한 뷰(View)를 다룰 때 `db.table()` 대신 새로운 `db.view()` 메서드를 사용하도록 코드를 수정하는 검증 단계를 거치시는 것이 안전합니다.
마이그레이션 시스템에서 역방향 마이그레이션을 제공하지 않고 실수를 새 마이그레이션으로만 해결하도록 설계한 점은 단순하지만 우려되는 부분도 있습니다. 이러한 단순화된 설계가 복잡한 데이터베이스 환경에서 예상치 못한 문제를 일으키지는 않을까요?
역방향 마이그레이션이 없어 복잡한 환경에서 대처가 어려울지 우려하시는 부분은 합리적입니다. 본문에서는 설계가 의도적으로 단순하게 유지되었으며, 실수가 생기면 이를 되돌리는 새 마이그레이션을 적용해 해결하는 방식을 권장합니다. 이 시스템의 기반인 `sqlite-migrate`가 이미 LLM 및 여러 프로젝트에서 수년간 안정적으로 작동하며 설계의 안정성을 증명했다는 점을 참고하실 수 있습니다.
sqlite-utils 4.0rc1에서 중첩 트랜잭션을 지원하는 db.atomic() 기능이 추가되어 정말 반갑네요. 기존에 sqlite-migrate를 따로 쓰지 않고도 이제 마이그레이션 기능을 내장으로 바로 쓸 수 있게 된 점도 실무에 큰 도움이 될 것 같습니다. 이번 RC 버전을 바로 테스트해보고 싶으신 분들이 계신가요?
새로운 `db.atomic()`과 내장 마이그레이션 기능은 실무 생산성을 크게 높여줄 수 있습니다. 이번 RC 버전은 `pip install sqlite-utils==4.0rc1` 명령어나 uvx 도구를 통해 쉽게 설치해 테스트해 보실 수 있어요. 특히 중첩 트랜잭션을 지원하는 `db.atomic()` 기능은 기존 방식에 비해 덜 검증된 상태라 더 많은 실무자분들의 테스트 참여가 필요한 상황입니다.