dockerで環境を作成しています
使用イメージ : postgres:16
os : Debian GNU/Linux 12 (bookworm)
postgresql : psql (PostgreSQL) 16.4 (Debian 16.4-1.pgdg120+2)
golang-migrateをインストール
# apt-get update && apt-get upgrade -y
# apt-get install tar gzip curl vim
# curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.0/migrate.linux-amd64.tar.gz | tar xvz
# mv ./migrate /usr/bin/migrate
利用できるかチェック
$ migrate -help
公式のPostgreSQLのチュートリアルを参考に進めていく
データベースの作成
psql -h localhost -U postgres -w -c "create database example;"
パスワードの変更をする場合は以下で行う
$ psql -h localhost -U postgres
postgres=# \password
Enter new password for user "postgres":
Enter it again:
テーブルの作成
$ migrate create -ext sql -dir db/migrations -seq create_users_table
/var/lib/postgresql/db/migrations/000001_create_users_table.up.sql
/var/lib/postgresql/db/migrations/000001_create_users_table.down.sql
CREATE文の作成
$ vim /var/lib/postgresql/db/migrations/000001_create_users_table.up.sql
CREATE TABLE IF NOT EXISTS users(
id serial PRIMARY KEY,
username VARCHAR (50) UNIQUE NOT NULL,
password VARCHAR (50) NOT NULL,
email VARCHAR (300) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
DROP文の作成
vim /var/lib/postgresql/db/migrations/000001_create_users_table.down.sql
DROP TABLE IF EXISTS users;
マイグレーションの実行前にテーブルの確認
$ psql example -c "\d users"
Did not find any relation named "users".
データベースURLが必要とのことなのでエクスポートを行う
$ export POSTGRESQL_URL='postgres://postgres:password@localhost:5432/example?sslmode=disable'
マイグレーションの実行
$ migrate -database ${POSTGRESQL_URL} -path db/migrations up
1/u create_users_table (12.606125ms)
テーブルの確認
$ sql example -c "\d users"
Table "public.users"
Column | Type | Collation | Nullable | Default
----------+------------------------+-----------+----------+----------------------------------------
user_id | integer | | not null | nextval('users_user_id_seq'::regclass)
username | character varying(50) | | not null |
password | character varying(50) | | not null |
email | character varying(300) | | not null |
Indexes:
"users_pkey" PRIMARY KEY, btree (user_id)
"users_email_key" UNIQUE CONSTRAINT, btree (email)
"users_username_key" UNIQUE CONSTRAINT, btree (username)
マイグレーションを行った内容を戻す
$ migrate -database ${POSTGRESQL_URL} -path db/migrations down
$ migrate -database ${POSTGRESQL_URL} -path db/migrations down
Are you sure you want to apply all down migrations? [y/N]
y
Applying all down migrations
1/d create_users_table (5.974338ms)
マイグレーションの管理はschema_migrationsテーブルで行っているようです
https://github.com/golang-migrate/migrate/blob/master/database/postgres/README.md
upを実行後
$ psql ${POSTGRESQL_URL} -c "select * from schema_migrations;"
version | dirty
---------+-------
1 | f
(1 row)
downを実行後
$ psql ${POSTGRESQL_URL} -c "select * from schema_migrations;"
version | dirty
---------+-------
(0 rows)
2回目のマイグレーションファイルを作成する
$ migrate create -ext sql -dir db/migrations -seq create_todo_table
$ vim /var/lib/postgresql/db/migrations/000002_create_todo_table.up.sql
CREATE TABLE todo (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(255) NOT NULL,
description TEXT,
due_date DATE,
is_completed BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
$ vim /var/lib/postgresql/db/migrations/000002_create_todo_table.down.sql
DROP TABLE IF EXISTS todo;
2回目のマイグレーションを実行
$ migrate -database ${POSTGRESQL_URL} -path db/migrations up
$ psql example -c "\d todo"
Table "public.todo"
Column | Type | Collation | Nullable | Default
--------------+-----------------------------+-----------+----------+----------------------------------
id | integer | | not null | nextval('todo_id_seq'::regclass)
user_id | integer | | not null |
title | character varying(255) | | not null |
description | text | | |
due_date | date | | |
is_completed | boolean | | | false
created_at | timestamp without time zone | | | CURRENT_TIMESTAMP
Indexes:
"todo_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"todo_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
問題なくテーブルの作成されています。
チュートリアルにあるenum_moodを作成します。
$ migrate create -ext sql -dir db/migrations -seq add_mood_to_users
$ vim /var/lib/postgresql/db/migrations/000003_add_mood_to_users.up.sql
$ vim /var/lib/postgresql/db/migrations/000003_add_mood_to_users.down.sql
$ migrate -database ${POSTGRESQL_URL} -path db/migrations up
gotoで特定バージョンまでdownする
$migrate -database ${POSTGRESQL_URL} -path db/migrations goto 1
バージョン2,3で作成したtodoテーブルとenum_moodが削除されていることを確認できました。
$ psql example -c "\d users"
Table "public.users"
Column | Type | Collation | Nullable | Default
------------+-----------------------------+-----------+----------+-----------------------------------
id | integer | | not null | nextval('users_id_seq'::regclass)
username | character varying(50) | | not null |
password | character varying(50) | | not null |
email | character varying(300) | | not null |
created_at | timestamp without time zone | | | CURRENT_TIMESTAMP
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"users_email_key" UNIQUE CONSTRAINT, btree (email)
"users_username_key" UNIQUE CONSTRAINT, btree (username)
$ psql example -c "\d"
List of relations
Schema | Name | Type | Owner
--------+-------------------+----------+----------
public | schema_migrations | table | postgres
public | users | table | postgres
public | users_id_seq | sequence | postgres
(3 rows)
まとめ
チュートリアルを参考にgolang-migrateを動かしてみました。使い方に関しては特に複雑なことはなく基本的な使い方は、時間をかからず理解できるのかなと感じました。
今回はCLIで動かしてみましたが、goアプリからも使うことができるようなので次回はgoアプリ内で動かしてみようと思います。