Dbmate は、複数の開発者と運用サーバー間でデータベース スキーマの同期を維持するデータベース移行ツールです。
これは、Go、Node.js、Python、Ruby、PHP、Rust、C++、またはデータベースを利用したアプリケーションの作成に使用しているその他の言語やフレームワークで使用できるスタンドアロンのコマンド ライン ツールです。これは、複数のサービスを異なる言語で作成しており、一貫した開発ツールを使用して健全性を維持したい場合に特に役立ちます。
dbmate と他の一般的なデータベース スキーマ移行ツールとの比較については、「代替手段」を参照してください。
schema.sql
ファイルの保存をサポートしますDATABASE_URL
) を使用して定義されるか、コマンド ラインで指定されます。.env
ファイルから環境変数を読み取るための組み込みサポート故宮
NPM を使用してインストールします。
npm install --save-dev dbmate
npx dbmate --help
macOS
Homebrew を使用してインストールします。
brew install dbmate
dbmate --help
Linux
バイナリを直接インストールします。
sudo curl -fsSL -o /usr/local/bin/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64
sudo chmod +x /usr/local/bin/dbmate
/usr/local/bin/dbmate --help
窓
スクープを使用してインストールする
scoop install dbmate
dbmate -- help
ドッカー
Docker イメージは GitHub Container Registry ( ghcr.io/amacneil/dbmate
) に公開されます。
忘れずに--network=host
を設定するか、Docker ネットワーキングで dbmate を使用するためのヒントについてはこのコメントを参照してください)。
docker run --rm -it --network=host ghcr.io/amacneil/dbmate --help
移行を作成または適用する場合は、Docker のバインド マウント機能を使用して、ローカル作業ディレクトリ ( pwd
) を dbmate コンテナ内で使用できるようにする必要があります。
docker run --rm -it --network=host -v " $( pwd ) /db:/db " ghcr.io/amacneil/dbmate new create_users_table
dbmate --help # print usage help
dbmate new # generate a new migration file
dbmate up # create the database (if it does not already exist) and run any pending migrations
dbmate create # create the database
dbmate drop # drop the database
dbmate migrate # run any pending migrations
dbmate rollback # roll back the most recent migration
dbmate down # alias for rollback
dbmate status # show the status of all migrations (supports --exit-code and --quiet)
dbmate dump # write the database schema.sql file
dbmate load # load schema.sql file to the database
dbmate wait # wait for the database server to become available
次のオプションはすべてのコマンドで使用できます。コマンドライン引数は、 dbmate [global options] command [command options]
の順序で使用する必要があります。ほとんどのオプションは、環境変数を介して構成することもできます (また、 .env
ファイルからロードされるため、チーム メンバー間で構成を共有するのに役立ちます)。
--url, -u "protocol://host:port/dbname"
- データベース URL を直接指定します。 (環境: DATABASE_URL
)--env, -e "DATABASE_URL"
- データベース接続 URL を読み取る環境変数を指定します。--env-file ".env"
- ロードする代替環境変数ファイルを指定します。--migrations-dir, -d "./db/migrations"
- 移行ファイルを保存する場所。 (環境: DBMATE_MIGRATIONS_DIR
)--migrations-table "schema_migrations"
- 移行を記録するデータベース テーブル(環境: DBMATE_MIGRATIONS_TABLE
)--schema-file, -s "./db/schema.sql"
- schema.sql ファイルを保持するパス。 (環境: DBMATE_SCHEMA_FILE
)--no-dump-schema
- 移行/ロールバック時に schema.sql ファイルを自動更新しません(環境: DBMATE_NO_DUMP_SCHEMA
)--strict
- 移行が順序どおりに適用されない場合は失敗します(環境: DBMATE_STRICT
)--wait
- 後続のコマンドを実行する前にデータベースが使用可能になるまで待機します(環境: DBMATE_WAIT
)--wait-timeout 60s
- --wait フラグのタイムアウト(環境: DBMATE_WAIT_TIMEOUT
) Dbmate は、デフォルトでDATABASE_URL
環境変数を使用してデータベースを検索します。 12 要素アプリを作成している場合は、すべての接続文字列を環境変数に保存する必要があります。
開発時にこれを容易にするために、dbmate は現在のディレクトリで.env
ファイルを検索し、そこにリストされているすべての変数を現在の環境で指定されているかのように処理します (ただし、既存の環境変数が優先されます)。
.env
ファイルがまだない場合は、ファイルを作成し、データベース接続 URL を追加します。
$ cat .env
DATABASE_URL= " postgres://[email protected]:5432/myapp_development?sslmode=disable "
DATABASE_URL
次の形式で指定する必要があります。
protocol://username:password@host:port/database_name?options
protocol
、 mysql
、 postgres
、 postgresql
、 sqlite
、 sqlite3
、 clickhouse
のいずれかである必要がありますusername
とpassword
URL エンコードする必要があります (特殊な文字を使用するとエラーが発生します)。host
ホスト名または IP アドレスのいずれかですoptions
ドライバー固有です (これらを使用したい場合は、基礎となる Go SQL ドライバーを参照してください) Dbmate は、別の環境変数から接続 URL をロードすることもできます。たとえば、テスト スイートを実行する前に、テスト データベースを削除して再作成することができます。これを行う簡単な方法の 1 つは、テスト データベース接続 URL をTEST_DATABASE_URL
環境変数に保存することです。
$ cat .env
DATABASE_URL= " postgres://[email protected]:5432/myapp_dev?sslmode=disable "
TEST_DATABASE_URL= " postgres://[email protected]:5432/myapp_test?sslmode=disable "
その後、テスト スクリプト (Makefile など) でこの環境変数を指定できます。
$ dbmate -e TEST_DATABASE_URL drop
Dropping: myapp_test
$ dbmate -e TEST_DATABASE_URL --no-dump-schema up
Creating: myapp_test
Applying: 20151127184807_create_users_table.sql
Applied: 20151127184807_create_users_table.sql in 123µs
あるいは、コマンド ラインで URL を直接指定することもできます。
$ dbmate -u " postgres://[email protected]:5432/myapp_test?sslmode=disable " up
dbmate -u $TEST_DATABASE_URL
よりもdbmate -e TEST_DATABASE_URL
を使用する唯一の利点は、前者では dbmate の.env
ファイルの自動ロードを利用できることです。
Postgres に接続する場合、dbmate はデフォルトで TLS 接続を必要とするため、接続文字列にsslmode=disable
オプションを追加する必要がある場合があります (他の一部のフレームワーク/言語ではデフォルトで暗号化されていない接続が許可されています)。
DATABASE_URL= " postgres://username:[email protected]:5432/database_name?sslmode=disable "
UNIX ソケット経由で接続するには、 socket
またはhost
パラメーターを指定できます (注: ディレクトリのみを指定します)。
DATABASE_URL= " postgres://username:password@/database_name?socket=/var/run/postgresql "
search_path
パラメータは、dbmate のschema_migrations
テーブルだけでなく、移行の適用中に現在のスキーマを指定するために使用できます。スキーマが存在しない場合は、自動的に作成されます。カンマで区切られた複数のスキーマが渡された場合、最初のスキーマがschema_migrations
テーブルに使用されます。
DATABASE_URL= " postgres://username:[email protected]:5432/database_name?search_path=myschema "
DATABASE_URL= " postgres://username:[email protected]:5432/database_name?search_path=myschema,public "
DATABASE_URL= " mysql://username:[email protected]:3306/database_name "
UNIX ソケットを介して接続するためにsocket
パラメーターを指定できます。
DATABASE_URL= " mysql://username:password@/database_name?socket=/var/run/mysqld/mysqld.sock "
SQLite データベースはファイル システムに保存されるため、ホストを指定する必要はありません。デフォルトでは、ファイルは現在のディレクトリを基準にしています。たとえば、次のコマンドは./db/database.sqlite3
にデータベースを作成します。
DATABASE_URL= " sqlite:db/database.sqlite3 "
絶対パスを指定するには、パスにスラッシュを追加します。以下は/tmp/database.sqlite3
にデータベースを作成します。
DATABASE_URL= " sqlite:/tmp/database.sqlite3 "
DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name "
ClickHouse クラスターを使用するには、次の 4 つの接続クエリ パラメーターを指定できます。
on_cluster
- クラスター ステートメントと複製された移行テーブルを使用することを示します。 (デフォルト: false
) このパラメータが指定されていない場合、他のクラスタ関連のクエリパラメータは無視されます。 DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster "
DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster=true "
cluster_macro
(オプション) - ON CLUSTER ステートメントおよび複製された移行テーブル エンジンの Zookeeper パスに使用されるマクロ値。 (デフォルト: {cluster}
) DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster&cluster_macro={my_cluster} "
replica_macro
(オプション) - 複製された移行テーブル エンジンのレプリカ名に使用されるマクロ値。 (デフォルト: {replica}
) DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster&replica_macro={my_replica} "
zoo_path
(オプション) - ClickHouse/Zoo Keeper のテーブル移行へのパス。 (デフォルト: /clickhouse/tables/<cluster_macro>/{table}
) DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster&zoo_path=/zk/path/tables "
サポートされているその他の接続オプションを参照してください。
GCP で実際の BigQuery に接続する場合は、 DATABASE_URL
の次の形式に従います。
bigquery://projectid/location/dataset
projectid
(必須) - プロジェクト ID
dataset
(必須) - プロジェクト内のデータセット名
location
(オプション) - データセットが作成される場所
注: 適切な認証のためにGOOGLE_APPLICATION_CREDENTIALS
環境変数を設定する方法については、このドキュメントに従ってください。
BigQuery エミュレータなどのカスタム エンドポイントに接続しようとする場合は、次の形式に従ってください。
bigquery://host:port/projectid/location/dataset?disable_auth=true
disable_auth
(オプション) - true
渡すと認証がスキップされ、テストとエミュレータへの接続にのみ使用されます。
現在、Spanner のサポートは PostgreSQL Dialect を使用するデータベースに限定されており、データベースの作成時に選択する必要があります。 GoogleSQL をサポートする今後の Spanner については、このディスカッションを参照してください。
Postgres インターフェイスを備えた Spanner では、PGAdapter が実行されている必要があります。 DATABASE_URL
には次の形式を使用し、ホストとポートは PGAdapter が実行されている場所に設定します。
DATABASE_URL= " spanner-postgres://127.0.0.1:5432/database_name?sslmode=disable "
認証は PGAdapter によって処理されるため、ユーザー名とパスワードを指定する必要はないことに注意してください (指定しても PGAdapter によって無視されます)。
postgres ドライバーの他のオプションもサポートされています。
また、Spanner では、明示的なトランザクション内で DDL を実行することもできません。したがって、DDL を含む移行では、 transaction:false
を指定する必要があります。
-- migrate:up transaction:false
CREATE TABLE ...
-- migrate:down transaction:false
DROP TABLE ...
pg_dump
Spanner によって提供されていない関数を使用するため、スキーマ ダンプは現在サポートされていません。
新しい移行を作成するには、 dbmate new create_users_table
を実行します。移行には好きな名前を付けることができます。これにより、現在のディレクトリにファイルdb/migrations/20151127184807_create_users_table.sql
が作成されます。
-- migrate:up
-- migrate:down
移行を記述するには、SQL をmigrate:up
セクションに追加するだけです。
-- migrate:up
create table users (
id integer ,
name varchar ( 255 ),
email varchar ( 255 ) not null
);
-- migrate:down
注: 移行ファイルの名前は
[version]_[description].sql
の形式で付けられます。データベースにはバージョン (ファイル名の先頭のすべての数字として定義) のみが記録されるため、現在のアプリケーションの状態に影響を与えることなく、移行ファイルの名前を安全に変更できます。
dbmate up
実行して保留中の移行を実行します。
$ dbmate up
Creating: myapp_development
Applying: 20151127184807_create_users_table.sql
Applied: 20151127184807_create_users_table.sql in 123µs
Writing: ./db/schema.sql
注:
dbmate up
データベースがまだ存在しない場合に作成します (現在のユーザーがデータベースを作成する権限を持っていると仮定します)。データベースを作成せずに移行を実行する場合は、dbmate migrate
実行します。
保留中の移行は常に番号順に適用されます。ただし、dbmate は、マイグレーションが個別にコミットされた場合 (たとえば、開発者がブランチで長期間作業しており、すでに他のバージョン番号よりも低いバージョン番号を持つマイグレーションをコミットした場合) に、マイグレーションが順番どおりに適用されることを防ぎません。移行が適用されると、dbmate は保留中の移行を単に適用します)。より詳細な説明については、#159 を参照してください。
デフォルトでは、dbmate は移行をロールバックする方法を知りません。開発では、データベースを以前の状態に戻せると便利なことがよくあります。これを実現するには、 migrate:down
セクションを実装します。
-- migrate:up
create table users (
id integer ,
name varchar ( 255 ),
email varchar ( 255 ) not null
);
-- migrate:down
drop table users;
dbmate rollback
を実行して、最新の移行をロールバックします。
$ dbmate rollback
Rolling back: 20151127184807_create_users_table.sql
Rolled back: 20151127184807_create_users_table.sql in 123µs
Writing: ./db/schema.sql
dbmate は、 key:value
ペアの形式で移行ブロックに渡されるオプションをサポートします。サポートされているオプションのリスト:
transaction
取引
トランザクション内で SQL を実行したくない場合は、 transaction
便利です。
-- migrate:up transaction:false
ALTER TYPE colors ADD VALUE ' orange ' AFTER ' red ' ;
データベースがサポートしている場合、 transaction
デフォルトでtrue
になります。
プロジェクトに Docker 開発環境を使用している場合、移行や単体テストの実行時にデータベースがすぐに準備できないという問題が発生する可能性があります。これは、データベース サーバーが起動したばかりであることが原因である可能性があります。
一般に、アプリケーションは、起動時にデータベース接続が機能しない場合でも回復力を備えている必要があります。ただし、移行や単体テストを実行する目的では、これは現実的ではありません。 wait
コマンドを使用すると、データベースが使用可能になるまでスクリプトまたは他のアプリケーションを一時停止できるため、この状況を回避できます。 Dbmate は、最大 60 秒まで、1 秒ごとにデータベース サーバーへの接続を試行します。
データベースが使用可能な場合、 wait
出力を返しません。
$ dbmate wait
データベースが使用できない場合は、データベースが使用可能になるまでwait
ブロックされます。
$ dbmate wait
Waiting for database....
データベースの準備ができていないことが原因でエラーが発生する場合は、他のコマンドで--wait
フラグを使用することもできます。
$ dbmate --wait up
Waiting for database....
Creating: myapp_development
--wait-timeout
使用してタイムアウトをカスタマイズできます (デフォルトは 60 秒)。データベースがまだ使用できない場合、コマンドはエラーを返します。
$ dbmate --wait-timeout=5s wait
Waiting for database.....
Error: unable to connect to database: dial tcp 127.0.0.1:5432: connect: connection refused
wait
コマンドは、指定したデータベースが存在するかどうかを検証するのではなく、サーバーが利用可能で準備ができていることだけを検証することに注意してください (したがって、データベース サーバーが利用可能であるが、データベースがまだ作成されていない場合は成功を返します)。
up
、 migrate
、またはrollback
コマンドを実行すると、dbmate はデータベース スキーマの完全な表現を含む./db/schema.sql
ファイルを自動的に作成します。 Dbmate はこのファイルを最新の状態に保つため、手動で編集しないでください。
コミットまたはプル リクエストでスキーマへの変更を簡単に確認できるように、このファイルをソース管理にチェックインすることをお勧めします。 (テスト ハーネスなどで) 各移行を順番に実行せずに、データベース スキーマをすばやくロードする場合にも、このファイルを使用することもできます。ただし、このファイルを保存したくない場合は、それを.gitignore
に追加するか、 --no-dump-schema
コマンド ライン オプションを渡します。
他のアクションを実行せずにschema.sql
ファイルをダンプするには、 dbmate dump
を実行します。他の dbmate アクションとは異なり、このコマンドは、PATH で使用できるそれぞれのpg_dump
、 mysqldump
、またはsqlite3
コマンドに依存します。これらのツールが使用できない場合、dbmate はup
、 migrate
、またはrollback
アクション中にスキーマ ダンプ ステップをサイレントにスキップします。 dbmate dump
実行して出力を確認することで、問題を診断できます。
$ dbmate dump
exec: " pg_dump " : executable file not found in $PATH
Ubuntu または Debian システムでは、 postgresql-client
、 mysql-client
、またはsqlite3
それぞれインストールすることでこの問題を修正できます。インストールするパッケージのバージョンが、データベース サーバーで実行されているバージョン以上であることを確認してください。
注:
schema.sql
ファイルには、一部のテーブルまたは列が dbmate 移行以外で作成された場合でも、データベースの完全なスキーマが含まれます。
Dbmate は、任意の言語またはフレームワークの CLI として使用できるように設計されていますが、Go アプリケーションのライブラリとして使用することもできます。
以下に簡単な例を示します。必要なドライバーを忘れずにインポートしてください。
package main
import (
"net/url"
"github.com/amacneil/dbmate/v2/pkg/dbmate"
_ "github.com/amacneil/dbmate/v2/pkg/driver/sqlite"
)
func main () {
u , _ := url . Parse ( "sqlite:foo.sqlite3" )
db := dbmate . New ( u )
err := db . CreateAndMigrate ()
if err != nil {
panic ( err )
}
}
その他のオプションについては、リファレンス ドキュメントを参照してください。
Go の埋め込み機能を使用して、移行をアプリケーション バイナリに埋め込むことができます。
db.FS
使用して、移行の読み取りに使用するファイルシステムを指定します。
package main
import (
"embed"
"fmt"
"net/url"
"github.com/amacneil/dbmate/v2/pkg/dbmate"
_ "github.com/amacneil/dbmate/v2/pkg/driver/sqlite"
)
//go:embed db/migrations/*.sql
var fs embed. FS
func main () {
u , _ := url . Parse ( "sqlite:foo.sqlite3" )
db := dbmate . New ( u )
db . FS = fs
fmt . Println ( "Migrations:" )
migrations , err := db . FindMigrations ()
if err != nil {
panic ( err )
}
for _ , m := range migrations {
fmt . Println ( m . Version , m . FilePath )
}
fmt . Println ( " n Applying..." )
err = db . CreateAndMigrate ()
if err != nil {
panic ( err )
}
}
移行ファイルは非常にシンプルで、デフォルトでは./db/migrations
に保存されます。 dbmate new create_users
を実行すると、 [date]_create_users.sql
という名前の新しい移行ファイルを作成できます。以下に例を示します。
-- migrate:up
create table users (
id integer ,
name varchar ( 255 ),
);
-- migrate:down
drop table if exists users;
編集しやすいように、上への移行と下への移行は両方とも同じファイルに保存されます。ダウン移行を実装しないことを選択した場合でも、アップ ディレクティブとダウン ディレクティブの両方が必要です。
移行を適用すると、dbmate は内容ではなくバージョン番号のみを保存するため、内容を変更する前に必ず移行をロールバックする必要があります。このため、バージョン番号を変更しない限り、適用ステータスに影響を与えることなく移行ファイルの名前を安全に変更できます。
スキーマ ファイルは、デフォルトで./db/schema.sql
に書き込まれます。これは、適用された移行やその他の変更を含む、データベース スキーマの完全なダンプです。
移行の差分を簡単に比較できるように、このファイルをソース管理にチェックインする必要があります。スキーマ ファイルを使用すると、すべての移行を実行する必要がなく、データベースを迅速に復元できます。
Dbmate は、適用された各移行のレコードをschema_migrations
という名前のテーブルに保存します。このテーブルがまだ存在しない場合は、自動的に作成されます。
表は非常にシンプルです:
CREATE TABLE IF NOT EXISTS schema_migrations (
version VARCHAR ( 255 ) PRIMARY KEY
)
--migrations-table
フラグまたはDBMATE_MIGRATIONS_TABLE
環境変数を使用して、このテーブルの名前をカスタマイズできます。
別のデータベース スキーマ移行ツールを使用する理由Dbmate は、他の多くのツール、主に Active Record Migrations からインスピレーションを受けており、構成が簡単で、言語やフレームワークに依存しないことを目標としています。ここでは、dbmate と他の一般的な移行ツールとの比較を示します。
データベースメイト | ガチョウ | SQL移行 | golang-移行 | アクティブレコード | 続編化する | フライウェイ | スクッチ | |
---|---|---|---|---|---|---|---|---|
特徴 | ||||||||
プレーン SQL 移行ファイル | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ||
データベースの作成と削除のサポート | ✅ | ✅ | ||||||
スキーマダンプファイルの保存のサポート | ✅ | ✅ | ||||||
タイムスタンプでバージョン管理された移行ファイル | ✅ | ✅ | ✅ | ✅ | ✅ | |||
カスタムスキーマ移行テーブル | ✅ | ✅ | ✅ | ✅ | ||||
データベースの準備ができるまで待機する機能 | ✅ | |||||||
環境変数からロードされたデータベース接続文字列 | ✅ | ✅ | ||||||
.env ファイルを自動的にロードする | ✅ | |||||||
個別の構成ファイルはありません | ✅ | ✅ | ✅ | ✅ | ✅ | |||
言語/フレームワークに依存しない | ✅ | ✅ | ✅ | ✅ | ✅ | |||
ドライバー | ||||||||
PostgreSQL | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
MySQL | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
SQLite | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
クリックハウス | ✅ | ✅ | ✅ | ✅ |
この表に誤りがあることに気付いた場合は、変更を提案してください。
Dbmate は Go で書かれており、プル リクエストを歓迎します。
テストは、docker compose を使用して実際のデータベースに対して実行されます。 Docker イメージを構築してテストを実行するには、次の手順を実行します。
$ make docker-all
開発シェルを開始するには:
$ make docker-sh