AIニュース最前線
最新ニュースAI日報Hacker日報週報動画AIツールトレンド企業

AIニュース最前線

世界中のAI最新情報を日本語で毎時更新

最新ニュース日報トレンド企業プレミアムRSS
© 2026 ainew.jp特定商取引法に基づく表記
ニュース一覧元記事を開く
Simon Willison Blog·2026年6月22日 08:35·約6分で読める

sqlite-utils 4.0rc1 がマイグレーションとネストトランザクションを追加

#SQLite#Python#データベースマイグレーション#オープンソース#開発ツール
TL;DR

Simon Willison が SQLite を操作する Python ライブラリ「sqlite-utils」のメジャーバージョンアップ版 4.0rc1 を公開し、データベースマイグレーション機能とネストトランザクション機能を追加した。

AI深層分析2026年6月22日 10:03
3
注目/ 5段階
深度40%
4
関連度30%
2
実用性20%
5
革新性10%
3

キーポイント

1

データベースマイグレーション機能の統合

既存の「sqlite-migrate」パッケージを改良して本ライブラリに直接バンドルし、Python コードでテーブル作成やカラム追加などの構造化変更をバージョン管理可能にした。

2

ネストトランザクションのサポート

RC1 で実装された主要機能の一つとして、複雑なデータベース操作におけるトランザクションのネスト処理が可能になった。

3

非互換性を含むメジャーバージョンアップ

v4 への移行に伴い一部後方互換性が崩れる変更が含まれているため、安定版リリース前に RC(Release Candidate)としてコミュニティのテストを求めている。

4

SQLite 操作の Python ライブラリとしての進化

JSON データからの自動テーブル作成や複雑なテーブル変換など、既存の高レベル操作機能を維持しつつ、開発ワークフローを強化した。

影響分析・編集コメントを表示

影響分析

このリリースは、軽量データベースである SQLite を使用する Python アプリケーション開発において、本格的なバージョン管理と移行ワークフローを実現した点で重要です。特に、外部パッケージへの依存を減らしライブラリ内部でマイグレーション機能を完結させたことで、開発環境の簡素化と保守性の向上に寄与します。ただし、メジャーバージョンアップに伴う互換性破壊があるため、既存プロジェクトでの導入には慎重なテストが必要となります。

編集コメント

SQLite を扱う Python エンジニアにとって、スキーマ管理の負担を減らす重要なアップデートです。特に、外部ツールに依存せずにライブラリ内で完結するマイグレーション機能は、小規模から中規模のプロジェクト開発効率を劇的に向上させる可能性があります。

sqlite-utils は、SQLite データベースを扱うための Python ライブラリと CLI ツールを組み合わせたものです。Python のデフォルトの sqlite3 パッケージ 上に、高度な操作セットを提供しており、複雑なテーブル変換 のサポートや、JSON データからの自動テーブル作成、その他多数の機能を備えています。

私は sqlite-utils 4.0rc1 をリリースしました。これは sqlite-utils v4 の最初のリリース候補です。メジャーバージョンのアップグレードには、いくつか(小規模な)後方互換性のない変更が含まれているため、安定版リリースを確定する前に、多くの人々にこのバージョンを試してもらいたいと考えています。

新機能:マイグレーション

今回の RC では、以前の 4.0 アルファ版と比較して、2 つの重要な新機能が追加されました。

1 つ目はデータベースマイグレーションのサポートです。これは完全に新しい実装ではなく、数年前に私がリリースした sqlite-migrate パッケージをわずかに修正してポートしたものです。このパッケージは時間の経過とともにその価値を実証してきたため、現在は sqlite-utils に直接バンドルする準備が整いました。

migrations.py ファイル内のマイグレーションセットの例は以下の通りです:

⟦CODE_0⟧

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 テーブルを作成する移行と、そのテーブルに列を追加する移行という 2 つの移行セットを定義するものです。

その後、これらの移行は Python を使用して実行できます:

db = Database("creatures.db")

migrations.apply(db)

または、コマンドラインの migrate コマンドを使用して実行することもできます:

sqlite-utils migrate creatures.db migrations.py

このシステムは意図的に小さく設計されており、逆方向への移行機能は提供していません。そのため、発生したミスタイクは、それを元に戻すために新しい移行をデプロイすることで修正する必要があります。

その前身となる機能は、LLM やその他のさまざまなプロジェクトで数年間使用されてきたため、設計が安定しており、よく機能していることに自信を持っています。

新しい移行機能の詳細は こちら でドキュメント化されています。

新機能:db.atomic() トランザクション

この機能は移行機能ほど頻繁に使用されるものではないため、テスターによる注意がより必要です。

以前は、sqlite_utils は主にユーザーにトランザクション管理を任せており、sqlite3 のメカニズムを直接再利用する with db.conn: 構文を通じて行われていました。

SQLite はセーブポイントの形式でネストされたトランザクションをサポートしているため、それらをできるだけ使いやすくする抽象化層を設けたいと思いました。

「アトミック」という用語は Django や Peewee から借用しました。新しい 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"})

詳細は ドキュメント をご覧ください。

後方互換性を破る変更点

v4 における後方互換性を破る変更点は、アルファ版のリリースノートで説明されています。4.0a0 を参照してください。

  • Upsert 操作は、SQLite バージョン 3.23.1 より後のすべてのバージョンにおいて、SQLite の INSERT ... ON CONFLICT SET 構文を使用するようになりました。これは、以前の INSERT OR IGNORE に続く UPDATE という動作に依存していたアプリケーションにとっては非常にわずかな破壊的変更です。(#652)
  • Python ライブラリのユーザーは、Database() コンストラクタに use_old_upsert=True を渡すことで、以前の実装をオプトインできます。詳細は「INSERT OR IGNORE を使用した代替の Upsert」をご覧ください。
  • Python 3.8 のサポートを終了し、Python 3.13 のサポートを追加しました。(#646)
  • sqlite-utils tui は now、sqlite-utils-tui プラグインによって提供されるようになりました。(#648)
  • テストスイートは、新しい INSERT ... ON CONFLICT SET 構文が追加される前の最後のバージョンである SQLite 3.23.1(2018-04-10 版)でも実行されるようになりました。(#654)

そして 4.0a1 では:

  • ブレイキングチェンジ:db.table(table_name) メソッドは現在、テーブルのみに対して動作します。SQL ビューにアクセスするには代わりに db.view(view_name) を使用してください。(#657)
  • table.insert_all() および table.upsert_all() メソッドは、辞書の代わりにリストまたはタプルのイテレータを受け付けるようになりました。最初の項目には列名を格納したリスト/タプルを指定する必要があります。詳細については「リストまたはタプルのイテレータからのデータ挿入」をご覧ください。(#672)
  • ブレイキングチェンジ:デフォルトの浮動小数点型カラムタイプが、浮動小数点値に対する正しい SQLite 型である REAL に変更されました(元は FLOAT)。これはデータの挿入時に自動検出されるカラムに影響を及ぼします。(#645)
  • パッケージングのために setup.py の代わりに pyproject.toml を使用しています。(#675)
  • Python API におけるテーブルは、作成された際に保持していた主キーやその他のスキーマ詳細をより適切に記憶するようになりました。(#655)
  • ブレイキングチェンジ:table.convert() および sqlite-utils convert メカニズムは、False と評価される値をスキップしなくなりました。以前は --skip-false オプションが必要でしたが、これは削除されました。(#542)
  • ブレイキングチェンジ:このライブラリによって作成されたテーブルは、スキーマにおいてテーブル名と列名を「二重引用符」で囲むようになりました(以前は [角括弧] を使用していました)。(#677)
  • --functions CLI 引数は、Python コードの文字列を受け付けるだけでなく、Python ファイルへのパスも受け付けられるようになりました。また、この引数を複数回指定することも可能になりました。(#659)
  • ブレイキングチェンジ:CSV または TSV データをインポートする際の insert および upsert CLI コマンドにおいて、型検出がデフォルト動作となりました(以前は --detect-types フラグを渡さない限りすべてのカラムが TEXT として扱われていました)。古い動作に戻すには新しい --no-detect-types フラグを使用してください。SQLITE_UTILS_DETECT_TYPES 環境変数は削除されました。(#679)

実際に試してみましょう

新しい RC バージンは以下のようにインストールできます:

pip install sqlite-utils==4.0rc1

または、uvx を使って CLI バージンを直接試すことも可能です:

uvx --with sqlite-utils==4.0rc1 sqlite-utils --help

sqlite-utils Discord チャンネルで私たちとチャットしたり、GitHub Issues でバグを報告してください。

タグ: migrations, projects, sqlite, sqlite-utils, annotated-release-notes

原文を表示

sqlite-utils is my combined Python library and CLI tool for working with SQLite databases. It provides an extensive set of higher-level operations on top of Python's default sqlite3 package, including support for complex table transformations, automatic table creation from JSON data and a whole lot more.

I released sqlite-utils 4.0rc1, the first release candidate for sqlite-utils v4. The major version bump indicates some (minor) backwards incompatible changes, so I'm interested in having people try this out before I commit to a stable release.

New feature: migrations

There are two significant new features in this RC compared to the previous 4.0 alphas.

The first is support for database migrations. This isn't a completely new implementation - it's a slightly modified port of the sqlite-migrate package I released a few years ago. I think that package has proved itself over time, so I'm now ready to bundle it with sqlite-utils directly.

Here's what a set of migrations in a migrations.py file looks like:

code
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)

This defines a set of two migrations, one creating the creatures table and another adding a column to it.

You can then run those migrations either using Python:

code
db = Database("creatures.db")
migrations.apply(db)

Or with the command-line migrate command:

code
sqlite-utils migrate creatures.db migrations.py

The system is deliberately small: it doesn't provide reverse migrations, so any mistakes you make should be fixed by deploying a fresh migration to undo them.

Its predecessor has been used by LLM and various other projects for several years, so I'm confident that the design is stable and works well.

The new migrations feature is documented here.

New feature: db.atomic() transactions

This feature is a lot less exercised than migrations, so it deserves more attention from testers.

Previously, sqlite-utils mostly left transaction management up to its users, via a with db.conn: construct that reused the sqlite3 mechanism directly.

SQLite supports nested transactions in the form of savepoints, so I wanted an abstraction that could make those as easy to use as possible.

I borrowed the terminology "atomic" from Django and Peewee. Here's what the new API looks like:

code
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"})

More details in the documentation.

Backwards incompatible changes

The backwards incompatible changes in v4 were described in the alpha release notes. For 4.0a0:

Upsert operations now use SQLite's INSERT ... ON CONFLICT SET syntax on all SQLite versions later than 3.23.1. This is a very slight breaking change for apps that depend on the previous INSERT OR IGNORE followed by UPDATE behavior. (#652)

Python library users can opt-in to the previous implementation by passing use_old_upsert=True to the Database() constructor, see Alternative upserts using INSERT OR IGNORE.

Dropped support for Python 3.8, added support for Python 3.13. (#646)

sqlite-utils tui is now provided by the sqlite-utils-tui plugin. (#648)

Test suite now also runs against SQLite 3.23.1, the last version (from 2018-04-10) before the new INSERT ... ON CONFLICT SET syntax was added. (#654)

And for 4.0a1:

Breaking change: The db.table(table_name) method now only works with tables. To access a SQL view use db.view(view_name) instead. (#657)

The table.insert_all() and table.upsert_all() methods can now accept an iterator of lists or tuples as an alternative to dictionaries. The first item should be a list/tuple of column names. See Inserting data from a list or tuple iterator for details. (#672)

Breaking change: The default floating point column type has been changed from FLOAT to REAL, which is the correct SQLite type for floating point values. This affects auto-detected columns when inserting data. (#645)

Now uses pyproject.toml in place of setup.py for packaging. (#675)

Tables in the Python API now do a much better job of remembering the primary key and other schema details from when they were first created. (#655)

Breaking change: The table.convert() and sqlite-utils convert mechanisms no longer skip values that evaluate to False. Previously the --skip-false option was needed, this has been removed. (#542)

Breaking change: Tables created by this library now wrap table and column names in "double-quotes" in the schema. Previously they would use [square-braces]. (#677)

The --functions CLI argument now accepts a path to a Python file in addition to accepting a string full of Python code. It can also now be specified multiple times. (#659)

Breaking change: Type detection is now the default behavior for the insert and upsert CLI commands when importing CSV or TSV data. Previously all columns were treated as TEXT unless the --detect-types flag was passed. Use the new --no-detect-types flag to restore the old behavior. The SQLITE_UTILS_DETECT_TYPES environment variable has been removed. (#679)

Try it out

You can install the new RC like this:

code
pip install sqlite-utils==4.0rc1

Or try the CLI version directly with uvx like this:

code
uvx --with sqlite-utils==4.0rc1 sqlite-utils --help

Come chat with us about it in the sqlite-utils Discord channel, or file any bugs in GitHub Issues.

Tags: migrations, projects, sqlite, sqlite-utils, annotated-release-notes

この記事をシェア

関連記事

Simon Willison Blog★32026年6月19日 04:03

datasette-acl 0.6a0 のリリース

Alex Garcia 氏らが中心となり、データセットのテーブル単位での権限管理から、一般リソース共有システムへと拡張された「datasette-acl」バージョン 0.6a0 が公開されました。これにより、複数ユーザー環境でリソースへのアクセス制御が細かく行えるようになります。

Simon Willison Blog★32026年6月17日 01:18

Simon Willison Blog の datasette-tailscale 0.1a0 リリース

Simon Willison が、Datasette サーバーを Tailscale ネットワークに接続する実験的プラグイン「datasette-tailscale」のバージョン 0.1a0 を公開した。これにより、認証キーとホスト名を指定してローカルサーバーから安全にデータへアクセスできるようになる。

Simon Willison Blog2026年6月11日 15:28

非同期注入ライブラリ「asyncinject」のバージョン0.7がリリース

Simon Willison氏が開発した非同期依存関係注入パターンをサポートするユーティリティライブラリ「asyncinject」のバージョン0.7が公開された。この更新は、Claude Fable 5がバグを特定し修正した結果によるものである。

今日のまとめ

AI日報で今日の重要ニュースをまとめ読み

ニュース一覧に戻る元記事を読む