SQLite Utils 4.1 のリリース
Simon Willison が発表した sqlite-utils 4.1 は、CLI コマンドで直接 Python コードブロックを指定してデータ生成や型定義を行う機能を追加し、データベース操作の柔軟性を大幅に向上させた。
キーポイント
Python コードブロックによる動的データ生成
sqlite-utils insert および upsert コマンドに --code オプションが追加され、CLI 上で Python コードを直接記述して行データを動的に生成・挿入できるようになった。
カラム型の明示的指定機能
--type オプションにより、CSV や TSV の読み込み時に自動判定される型をユーザーが明示的に上書きできるようになり、データ整合性の確保が可能になった。
既存パターンの自然な拡張
convert コマンドなどで既に実装されていたコードブロック実行の仕組みを、データ生成(insert)と型定義にも適用し、一貫した開発体験を提供している。
型指定の強化とインデックス管理
insert/upsertコマンドに--typeオプションが追加され、ZIPコードなど数値に見えるが文字列として保存すべきデータの扱いが可能になりました。また、既存のインデックスを名前で削除する機能や、標準入力からクエリを実行する機能が追加されました。
upsertの自動推論と厳格テーブルモード
既存のプライマリキーを持つテーブルへのupsertで--pkオプションが不要になり、transform機能を通じてSQLiteのstrict modeを切り替える機能が実装されました。
AIによるテスト駆動開発の実践
新機能の実装において、モデルに手動テストを実行させるプロンプトを使用し、自動テストでは見つけられなかった2つのエッジケースを特定・修正しました。
影響分析・編集コメントを表示
影響分析
このアップデートは、データエンジニアや開発者が CLI を介して複雑なデータ変換ロジックを実行する際のワークフローを簡素化し、外部ファイルの管理コストを削減します。特にスクリプトベースの自動化タスクにおいて、コードの可読性と実行効率を両立させる重要な機能強化と言えます。
編集コメント
SQLite を扱う開発者にとって、CLI の操作性が格段に向上する実用的なアップデートです。特にデータパイプラインの構築時に、外部ファイルの作成を省略できる点は大きなメリットとなります。
Release: sqlite-utils 4.1
数日前にリリースされた4.0以来の最初のドットリリースで、いくつかのマイナーな新機能が追加されました。
- sqlite-utils insert および sqlite-utils upsert コマンドは、--code オプションを受け付けるようになりました。これにより、ファイルからインポートする代わりに、挿入対象となる行を定義する rows() 関数または行のイテレータを含む Python コードブロック(または .py ファイルへのパス)を提供できるようになりました (#684)。
sqlite-utils にはすでに、CLI オプションとして Python コードブロックを渡す機能があり、例えば sqlite-utils convert コマンドでは以下のように使用できます:
sqlite-utils convert content.db articles headline '
def convert(value):
return value.upper()'
このパターンを拡張して、新しい行を直接生成できるようにしたのが今回の機能です:
sqlite-utils insert data.db creatures --code '
def rows():
yield {"id": 1, "name": "Cleo"}
yield {"id": 2, "name": "Suna"}
' --pk id
- sqlite-utils insert および sqlite-utils upsert コマンドは、--type column-name type オプションも受け付けるようになりました。これにより、テーブル作成時に自動的に選択される型を上書きできます。これは、ZIP コードのように整数に見えるが、先頭のゼロを保持するために TEXT として保存すべき CSV や TSV の列に対して有用です (#131)。
長年待ち望まれていた機能リクエストが、実は シンプルな実装 であることが判明しました。
- インデックス名を指定してインデックスを削除するための新しい
table.drop_index(name)メソッドと、sqlite-utils drop-indexコマンドが追加されました。両方ともignore=Trueまたは--ignoreを受け付けるため、存在しないインデックスを無視できます(#626)。
sqlite-utils queryは、クエリ部分に-を指定することで標準入力から SQL クエリを読み取れるようになりました。例えば、echo "select * from dogs" | sqlite-utils query dogs.db -のように使用します(#765)。
さらに小さな機能 2 つを追加しました。Codex にすべての未解決の課題をレビューさせ、最も簡単なものを目立たせました!
sqlite-utils upsertは、既存テーブルの主キーを自動的に推論できるようになりました。そのため、主キーが既に定義されているテーブルに対してアップサートする際、--pkオプションを省略できます。
これも Codex の提案によるものです。Python ライブラリの改善として 4.0 リリースで提供された機能から、明らかに CLI で不足していた機能を追加しました。
table.transform()とtable.transform_sql()は、テーブルの SQLite ストリクトモードを変更するためにstrict=Trueまたはstrict=Falseを受け付けるようになりました。このオプションを省略すると、既存のモードが維持されます(#787)。
sqlite-utils transformコマンドも、テーブルのストリクトモードを変更するために--strictと--no-strictを受け付けるようになりました(#787)。
これら 2 つは、Evan Hahn による SQLite では STRICT テーブルを優先する という記事に触発されたものです。この記事は本日、Hacker News で話題になりました。Evan は次のように指摘しています:
残念ながら、テーブルを厳格モードに変更する ALTER 文には方法がないと考えています。非厳格なテーブルからデータを抽出し、厳格なテーブルにコピーする必要があります。
これはまさに sqlite-utils の transform メカニズム が行うことであり、私はこれを拡張して、テーブルを厳格モードと非厳格モードの間で切り替える機能を追加しました。
これらの新しい厳格テーブル機能を実装するために使用した GPT-5.6 Sol xhigh Codex のトランスクリプト はこちらです。私が実行した最も有用なプロンプトの一つはこれでした:
use uv run python -c and manually exercise the new .transform(strict=) option, see if you can find any edge-cases or bugs
これは、モデルに対して既に作成済みの自動テストの外側で手動テストを実行するよう指示するものでした。これにより、2 つの軽微な問題が発見され、その後修正されました。
Tags: projects, python, sqlite, sqlite-utils, annotated-release-notes, ai-assisted-programming
原文を表示
Release: sqlite-utils 4.1
The first dot-release since 4.0 a few days ago, introducing a number of minor new features.
sqlite-utils insert and sqlite-utils upsert now accept a --code option for providing a block of Python code (or a path to a .py file) that defines a rows() function or rows iterable of rows to insert, as an alternative to importing from a file. (#684)
sqlite-utils already had features that allow you to pass blocks of Python code as CLI arguments, for example this one for the sqlite-utils convert command:
sqlite-utils convert content.db articles headline '
def convert(value):
return value.upper()'Allowing blocks of code to generate new rows directly was on obvious extension of that pattern:
sqlite-utils insert data.db creatures --code '
def rows():
yield {"id": 1, "name": "Cleo"}
yield {"id": 2, "name": "Suna"}
' --pk idsqlite-utils insert and sqlite-utils upsert now accept --type column-name type to override the type automatically chosen when the table is created. This is useful for CSV or TSV columns such as ZIP codes that look like integers but should be stored as TEXT to preserve leading zeros. (#131)
A long-standing feature request which turned out to be a simple implementation.
New table.drop_index(name) method and sqlite-utils drop-index command for dropping an index by name. Both accept ignore=True/--ignore to ignore a missing index. (#626)
sqlite-utils query can now read the SQL query from standard input by passing - in place of the query, for example echo "select * from dogs" | sqlite-utils query dogs.db -. (#765)
Two more small features. I had Codex review all open issues and highlight the easiest ones!
sqlite-utils upsert can now infer the primary key of an existing table, so --pk can be omitted when upserting into a table that already has a primary key.
Another Codex suggestion, an obvious missing CLI feature from a Python library improvement that shipped in the 4.0 release.
table.transform() and table.transform_sql() now accept strict=True or strict=False to change a table’s SQLite strict mode. Omitting the option preserves the existing mode. (#787)
The sqlite-utils transform command now accepts --strict and --no-strict to change a table’s strict mode. (#787)
These two were inspired by Prefer STRICT tables in SQLite by Evan Hahn, which did the rounds on Hacker News today. Evan pointed out that:
Unfortunately, I don’t think there’s a way to ALTER a table to make it strict. I think you have to copy the data out of the non-strict table into the strict one.
That's exactly what the sqlite-utils transform mechanism does, so I extended it to add the ability to switch tables from strict to non-strict and vice-versa.
Here's the GPT-5.6 Sol xhigh Codex transcript I used to implement those new strict table features. One of the most useful prompts I ran was this one:
use uv run python -c and manually exercise the new .transform(strict=) option, see if you can find any edge-cases or bugs
Effectively telling the model to manually test its work, outside of the automated tests it had already written. This turned up two minor issues that we then fixed.
Tags: projects, python, sqlite, sqlite-utils, annotated-release-notes, ai-assisted-programming
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み