- SQLスキーマ間の差分(diff) を比較して、データベースマイグレーションを管理するCLIベースのツール
- 一般的なSQL DDL構文を使ってRDBMSスキーマを管理できる
- MySQL、MariaDB、TiDB、PostgreSQL、SQL Server、SQLite3 など主要なデータベースをサポート
- WebサイトではWebAssemblyビルドを活用したオンラインデモを通じて、スキーマ比較およびDDL生成機能を体験可能
- データベース変更作業を冪等的(idempotent) に管理できるため、安定したスキーマ同期に役立つ
sqldef 概要
- sqldefは、2つのSQLスキーマを比較(diff)して差分を分析し、それに基づいてDDLコマンドを生成するCLIツール
- ユーザーは既存スキーマと目標スキーマを比較し、必要な変更点を自動的に導き出せる
- 一般的なSQL DDL構文をそのまま使ってマイグレーションを実行できる
- 対応データベースとしてMySQL、MariaDB、TiDB、PostgreSQL、SQL Server、SQLite3が明記されている
オンラインデモ機能
- WebサイトにはOnline Demoが用意されており、スキーマ変更を視覚的に確認できる
- 「Enable DROP」オプションで、削除コマンドを含めるかどうかを制御できる
- 「Up (current → desired)」セクションでは、新しいカラム追加、インデックス作成、制約追加などのDDL例を表示
- 「Down (desired → current)」セクションでは、制約削除などの逆方向変更の例を提供
動作方式
- オンラインデモはsqldefのWebAssemblyビルドを使用して、ブラウザ内でSQLスキーマ比較(diff)を実行
- 2つのスキーマ間の差分を計算し、その結果として必要なDDLコマンドを自動生成
- GitHubリポジトリのリンクからWebAssemblyビルドのソースを確認可能
1件のコメント
Hacker Newsのコメント
Postgres向けにより包括的なカバレッジが欲しいなら、私が作った pgschema を見てみるとよいかもしれない
去年の夏にはかなり完成したと思っていたが、6か月の間にユーザーが報告した 100件以上の課題 を解決しながら、自分がどれほど甘かったかを思い知った
複数のデータベースクラスタ間の不一致をチェックする機能もサポートしているのか気になる
SQLiteで試してみたが、既存テーブルに外部キー制約を追加するような難しいマイグレーションでは無効なSQLを生成する
例えば
ALTER TABLE books ADD CONSTRAINT fk_books_author FOREIGN KEY (author_id) REFERENCES authors (id)のような構文は SQLite では許可されていない関連ドキュメントは SQLite ALTER TABLE を参照
私は Atlas を使っている
マイグレーションベースとスキーマベースにはそれぞれ長所と短所があるので、同じプロジェクト内でも両方を併用している
スキーマベースは開発速度を高め、マイグレーションベースはより 信頼できるデプロイ を可能にする
Atlas は PR で自動的にマイグレーションを生成するため、ほとんどの開発者はバージョン管理ワークフローを直接扱わない
関連ドキュメント: Declarative vs Versioned Workflows, Atlas Action
明示的な migration flow のサポート が気に入った。実際にデプロイする前に、どんな変更が適用されるのか正確に知りたい
バックグラウンドマイグレーション をサポートする良いツールがあるのか気になる
例えば、大規模テーブルに一時的な nullable カラムを追加し、新しいコードがそのカラムにデータを書き始め、その後バックグラウンドで既存データをバッチで埋め、最後に non-nullable に変えるといった作業
こうした手続き的変更を宣言的に表現し、コードと一緒に レビュー・テスト できるツールがあるとよい
今はたいてい 一時的なスクリプトと手動のデプロイ手順 で対応している
開発環境での設定が簡単で、FastEndpoints-SqlJobQueues のような例もある
このツールは本当に素晴らしい
おかげで同じものを作ろうとしていた自分の 趣味プロジェクト をやめられる
その代わり、すでに100回くらい解かれている別の問題を扱う新しいプロジェクトを始めるつもりだ。例えば systemd のログを監視してエラーをメールで送るような簡単なツール
また別のマイグレーションマネージャではなく、小さくて便利なツール だという点がうれしかった
SQL の弱点をうまく補ってくれる感じがする。Spanner DDL のように宣言的であってほしいとも思う
Postgres ではスキーマスクリプトを idempotent に保つようにしている。
CREATE TABLE IF NOT EXISTSで始め、新しいカラムを追加するときはALTERを別に置くただ、時間が経つとスクリプトが複雑になり、安定してきたら ALTER 文を整理する
もし古いバックアップを復元する必要がある場合、こういうツールが互換性を素早く合わせてくれそうだ
Entity Framework や sqitch/liquibase と比べるとどうなのか気になる
宣言的アプローチは理解できるが、大規模な本番DBではマイグレーションは単純に宣言的ではない
理想的なスキーマ管理ツールは クエリコストとダウンタイムを最小化する戦略 を理解しているべきだ
カラム追加やインデックス変更はテーブル全体のスキャンを引き起こすことがある
例えば Fullname を FirstName と LastName に分ける場合、単純な diff では半分しか表現できない
EF Core では Up/Down メソッドで 可逆変換 を扱う
こうした概念なしにデータ変換をどう扱うのか気になる
私たちは独自に XML ベースの変換ツールを作った
XML は SQL よりパースしやすいので、XML に定義されたスキーマと DB を比較して必要な変更だけを適用する
Sybase SQLAnywhere を使っていたが、materialized view が絡むとカラムの追加・削除時にビューやインデックスを作り直さなければならない複雑さがあった
そのため安全装置を入れ、カラム削除は明示的な場合にだけ許可し、型変更も安全な場合にのみ実行するようにした
何百ものオンプレミス環境でのマイグレーションを 非常に簡単に してくれた
XML を修正するだけでツールが処理し、必要になれば機能を追加できる
SQLite ではカラム削除の扱いがうまくいかない
最近のバージョンでようやく DROP COLUMN が追加されたが、ほとんどのデバイスではまだサポートされていない
例では
x integer not nullを追加して DROP を試したが、“-- Skipped” というメッセージが出るだけだった標準的な方法は 一時テーブルを作ってデータをコピーしてから置き換える ことだが、このツールはそれを自動化しない
制約が絡むとミスしやすい部分なので惜しい
結局、簡単な作業しか処理しないなら手作業のほうがよいという気もする
このツールは 空のデータベース でしか有用に見えない
データマイグレーションは扱えず、例えば JSONB カラムを構造化された形に変えるケースや、カラム削除後の逆マイグレーションで
ADD COLUMN … NOT NULLを生成するような、実データのあるテーブルでは使えない