Go Migrate チュートリアル

1. Go Migrate の概要

Go MigrateはGo言語で記述されたデータベースマイグレーションを管理するためのツールです。これはコマンドラインインターフェース(CLI)として使用するか、Goプロジェクトのライブラリとしてインポートすることができます。Go Migrateは異なるソースからマイグレーションファイルを読み込み、それらを正しい順序でデータベースに適用することができます。さまざまなデータベースドライバーとマイグレーションソースがサポートされています。

2. バージョン

Go Migrateは複数のバージョンに対応しています。

  • Master: 最新バージョンで、新機能とバグ修正が含まれています
  • v4: 安定したバージョンであり、本番環境に適しています
  • v3: もはやサポートされておらず、使用すべきではありません

3. インストール

Go Migrateを使用するには、Goパッケージをインストールする必要があります。インストールには、次のコマンドを実行します。

go get -u -d github.com/golang-migrate/migrate/v4
cd $GOPATH/src/github.com/golang-migrate/migrate/v4

3. Go Migrateの使用

Go MigrateはCLIやGoプロジェクトのライブラリとして使用することができます。

3.0. データベース接続URL

CLIを使用するか、Goコードを記述するかに関わらず、データベースURLを設定する必要があります。

URL形式:

dbdriver://username:password@host:port/dbname?param1=true&param2=false

このURLはデータベースに接続し、接続パラメータを指定するためのものです。各部分の説明は以下の通りです。

  1. dbdriver://: これは使用するデータベースドライバーを指定するためのプロトコル識別子です。例: mysql.
  2. username:password: これは認証に使用するユーザー名とパスワードです。通常、ユーザー名とパスワードはコロン(:)で区切られます。
  3. @: この記号はホスト名とポート番号をユーザー名とパスワードから分けるために使用されます。
  4. host:port: これはデータベースサーバーのホスト名とポート番号です。ホスト名はデータベースサーバーのIPアドレスまたはドメイン名であり、ポート番号はデータベースサーバーがリッスンしているポートです。
  5. /dbname: これは接続するデータベースの名前です。
  6. ?param1=true&param2=false: この部分は追加の接続パラメータを指定するためのクエリパラメータです。この例では、2つのパラメータがあります。

これらのクエリパラメータは、データベースドライバーやデータベースサーバーの特定の要件に応じて設定することができ、接続の特定の属性や動作を構成するために使用されます。

Postgres接続パラメータ

postgres://postgres:password@localhost:5432/example?sslmode=disable

SQLite接続パラメータ

sqlite3://path/to/database?query

MongoDB接続パラメータ

mongodb://user:password@host:port/dbname?query

3.1 CLIの使用

3.1.1 基本的な使用法

CLIを使用するには、次のコマンドを実行します。

migrate -source file://path/to/migrations -database postgres://localhost:5432/database up 2

このコマンドは、指定されたソースからマイグレーションをデータベースに適用します。数字の「2」は適用するマイグレーションの数を示しています。

3.1.2 Dockerの使用

Go MigrateはDockerとも使用することができます。次のコマンドを実行します。

docker run -v {{ migration dir }}:/migrations --network host migrate/migrate -path=/migrations/ -database postgres://localhost:5432/database up 2

このコマンドは、Dockerコンテナ内でGo Migrateを実行し、指定されたソースからマイグレーションをデータベースに適用します。

3.2 Goプロジェクトでの使用方法

GoプロジェクトでGo Migrateを使用するには、必要なパッケージとライブラリをインポートする必要があります。以下は例です:

import (
    "github.com/golang-migrate/migrate/v4"
    _ "github.com/golang-migrate/migrate/v4/database/postgres"
    _ "github.com/golang-migrate/migrate/v4/source/github"
)

func main() {
    m, err := migrate.New(
        "github://mattes:personal-access-token@mattes/migrate_test",
        "postgres://localhost:5432/database?sslmode=enable")
    m.Steps(2)
}

このコードは、指定されたソースとデータベースを使用してGo Migrateを初期化し、Stepsメソッドを使用して2つのマイグレーションを適用します。

既存のデータベースクライアントを使用する場合は、次の例を参照してください:

import (
    "database/sql"
    _ "github.com/lib/pq"
    "github.com/golang-migrate/migrate/v4"
    "github.com/golang-migrate/migrate/v4/database/postgres"
    _ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
    db, err := sql.Open("postgres", "postgres://localhost:5432/database?sslmode=enable")
    driver, err := postgres.WithInstance(db, &postgres.Config{})
    m, err := migrate.NewWithDatabaseInstance(
        "file:///migrations",
        "postgres", driver)
    m.Up()
}

このコードは必要なパッケージをインポートし、sqlパッケージを使用してデータベースクライアントを初期化します。その後、NewWithDatabaseInstanceメソッドを使用して新しいGo Migrateインスタンスを作成し、ソースとデータベースドライバーを指定します。最後に、Upメソッドを使用してマイグレーションを適用します。

4. サポートされているデータベースドライバー

Go Migrateは、以下を含む複数のデータベースドライバーをサポートしています:

  • PostgreSQL
  • PGX v4
  • PGX v5
  • Redshift
  • Ql
  • Cassandra
  • SQLite
  • SQLite3
  • SQLCipher
  • MySQL/MariaDB
  • Neo4j
  • MongoDB
  • CrateDB
  • Shell
  • Google Cloud Spanner
  • CockroachDB
  • YugabyteDB
  • ClickHouse
  • Firebird
  • MS SQL Server

5. サポートされているマイグレーションソース

Go Migrateは、以下を含む複数のマイグレーションソースをサポートしています:

  • ファイルシステム:ローカルファイルシステムからのマイグレーションの読み込み。
  • io/fs:Go io/fsパッケージを使用したマイグレーションの読み込み。
  • Go-Bindata:jteeuwen/go-bindataパッケージを使用した埋め込みバイナリデータからのマイグレーションの読み込み。
  • pkger:markbates/pkgerパッケージを使用した埋め込みバイナリデータからのマイグレーションの読み込み。
  • GitHub:リモートGitHubリポジトリからのマイグレーションの読み込み。
  • GitHub Enterprise:リモートGitHub Enterpriseリポジトリからのマイグレーションの読み込み。
  • Bitbucket:リモートBitbucketリポジトリからのマイグレーションの読み込み。
  • Gitlab:リモートGitlabリポジトリからのマイグレーションの読み込み。
  • AWS S3:Amazon Web Services S3からのマイグレーションの読み込み。
  • Google Cloud Storage:Google Cloud Platform Storageからのマイグレーションの読み込み。

プロジェクトの要件に応じて、上記のサポートされるファイルストレージソースにデータベースマイグレーションファイルを格納できます。

6. マイグレーションファイル

Go Migrateのマイグレーションファイルには特定のファイル名とコンテンツ形式があります。

6.1 マイグレーションファイル名の形式

各マイグレーションには、"up"マイグレーションファイルと対応する"down"マイグレーションファイルがあります。マイグレーションファイル名は以下の形式に従う必要があります:

{version}_{title}.up.{extension}
{version}_{title}.down.{extension}

versionは、マイグレーションが適用される順序を表す一意の番号です。titleはマイグレーションのオプションの説明です。extensionは使用されているデータベースシステムによって異なります(例:SQLのバリアントでは.sqlを使用)。

6.2 マイグレーションコンテンツの形式

マイグレーションファイルのコンテンツは、データベースシステムによって異なりますが、通常は直接SQLを記述することが含まれます。

例えば、以下は2つのマイグレーションファイルです:

  • 000001_create_users_table.up.sql
  • 000001_create_users_table.down.sql

マイグレーションファイル000001_create_users_table.up.sql

CREATE TABLE IF NOT EXISTS users(
   user_id serial PRIMARY KEY,
   username VARCHAR (50) UNIQUE NOT NULL,
   password VARCHAR (50) NOT NULL,
   email VARCHAR (300) UNIQUE NOT NULL
);

マイグレーションファイル000001_create_users_table.down.sqlでは、downファイルは前の操作を取り消すために主に使用され、通常はロールバックの目的で使用されます。

DROP TABLE IF EXISTS users;

6.3 マイグレーションの可逆性

可逆的なマイグレーションの記述は、ベストプラクティスとされています。これは、upおよびdownのマイグレーションが任意のバージョンで実行できるほか、データベースの状態を再作成し、クリーンアップできることを意味します。

可逆性を確保するために、各マイグレーションにはそれに対応する「up」および「down」のマイグレーションファイルが必要です。「up」マイグレーションファイルにはマイグレーションを適用する操作が含まれ、一方、「down」マイグレーションファイルにはマイグレーションを元に戻す操作が含まれます。

7. MySQLの使用

Go MigrateはMySQLデータベースをサポートしています。MySQLデータベースに接続するには、以下のフォーマットのデータベースURLが必要です。

mysql://user:password@tcp(host:port)/dbname?query

URLには、マイグレーションテーブルの名前、TLSパラメータなどのクエリパラメータを含めることができます。クエリパラメータの完全な一覧については、Go Migrate MySQLドキュメントを参照してください。

7.1 URLクエリパラメータ

  • x-migrations-table: マイグレーションテーブルの名前。
  • x-no-lock: GET_LOCK/RELEASE_LOCKステートメントをスキップするにはtrueを設定します。マルチマスターMySQLバージョン向けに便利です。
  • x-statement-timeout: 指定したミリ秒数を超えるステートメントを中止します。
  • dbname: 接続するデータベースの名前。
  • user: ログインするユーザー。
  • password: ユーザーのパスワード。
  • host: 接続するホスト。
  • port: バインドするポート。
  • tls: TLS/SSL暗号化接続パラメータ。
  • x-tls-ca: CA(認証局)ファイルの場所。
  • x-tls-cert: クライアント証明書ファイルの場所。
  • x-tls-key: プライベートキーファイルの場所。
  • x-tls-insecure-skip-verify: SSLを使用するかどうか。

7.2 既存のクライアントとの使用

既存のMySQLクライアントとGo Migrateを使用する場合は、クライアントを作成する際にmultiStatements=trueパラメータを使用するようにしてください。以下に例を示します。

package main

import (
    "database/sql"
    
    _ "github.com/go-sql-driver/mysql"
    "github.com/golang-migrate/migrate/v4"
    "github.com/golang-migrate/migrate/v4/database/mysql"
    _ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
    db, _ := sql.Open("mysql", "user:password@tcp(host:port)/dbname?multiStatements=true")
    driver, _ := mysql.WithInstance(db, &mysql.Config{})
    m, _ := migrate.NewWithDatabaseInstance(
        "file:///migrations",
        "mysql", 
        driver,
    )
    
    m.Steps(2)
}

このコードは必要なパッケージをインポートし、MySQLデータベースクライアントを作成し、データベースインスタンスでGo Migrateを初期化します。次に、Stepsメソッドを使用して2つのマイグレーションを適用します。