ソースコード
package main
import (
"database/sql"
"fmt"
"log"
_ "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(){
// PostgreSQL に接続
db, err := sql.Open("postgres", "postgres://postgres:password@localhost:5432/dbname?sslmode=disable&search_path=test_schema")
if err != nil {
log.Fatalf("Failed to connect to the database: %v", err)
}
defer db.Close()
// マイグレーションを準備
driver, err := postgres.WithInstance(db, &postgres.Config{})
if err != nil {
log.Fatalf("Could not create postgres driver: %v", err)
}
// マイグレーションのインスタンスを作成
m, err := migrate.NewWithDatabaseInstance(
"file://db/migrations",
"postgres", driver)
if err != nil {
log.Fatalf("Failed to create migrate instance: %v", err)
}
// マイグレーションの実行
if err := m.Up(); err != nil && err != migrate.ErrNoChange {
log.Fatalf("Could not run up migrations: %v", err)
} else {
fmt.Println("Migrations applied successfully!")
}
}
処理の内容
-
DBと接続
接続するDBの情報を指定します。スキーマを指定することが多いかと思うので、「?search_path=」で対象のスキーマを指定してあげます。
処理が終了した際にか必ずDB接続を閉じるように「defer db.Close()」の宣言をします。db, err := sql.Open("postgres", "postgres://postgres:password@postgres-db:5432/example?sslmode=disable&search_path=test_schema") if err != nil { log.Fatalf("Failed to connect to the database: %v", err) } defer db.Close()
-
インスタンスの作成
マイグレーションを行うためのインスタンスを作成します。接続情報の不備などがあればここでエラーが発生します。// マイグレーションを準備 driver, err := postgres.WithInstance(db, &postgres.Config{}) if err != nil { log.Fatalf("Could not create postgres driver: %v", err) } // マイグレーションのインスタンスを作成 m, err := migrate.NewWithDatabaseInstance( "file://db/migrations", "postgres", driver) if err != nil { log.Fatalf("Failed to create migrate instance: %v", err) }
また「"file://db/migrations"」と記載をしていますが、ファイルシステムではなくAWS S3やGithubにも対応できるようです。
- ファイルシステム: file://path/to/migrations
- AWS S3 バケット: s3://bucket-name/path/to/migrations
- GitHub: github://owner/repo/path/to/migrations
-
マイグレーションの実行
実際にUp()を使用して、マイグレーションを実行します。// マイグレーションの実行 if err := m.Up(); err != nil && err != migrate.ErrNoChange { log.Fatalf("Could not run up migrations: %v", err) } else { fmt.Println("Migrations applied successfully!") }
まとめ
今回はgolang-migrateをCLIではなくgoアプリケーションから実行してみました。
今回はファイルシステムのマイグレーションファイルをもとに実行してみましたが、実際にアプリケーションで使用する際はAWS S3やGitHubから使用するほうが多いのではないかと思いました。