Help us understand the problem. What is going on with this article?

Go製マイグレーションツールまとめ

More than 3 years have passed since last update.

比較対象

  • CLIで使える
  • MySQLが使える
名前 Star数 スキーマ 方式 Dry Run 設定
liamstask/goose - Go/SQL Up/Down - YAML
mattes/migrate 892 SQL Up/Down - -
rubenv/sql-migrate 576 SQL Up/Down YAML
elwinar/rambler 371 SQL Up/Down - JSON
naoina/migu 29 Go(struct) Sync -
dev-cloverlab/carpenter 12 JSON/実DB Sync -

2017/01時点

今回比較しなかったもの

liamstask/goose

https://bitbucket.org/liamstask/goose

対応DB

  • MySQL
  • PostgreSQL
  • SQLite3

インストール

go get bitbucket.org/liamstask/goose/cmd/goose

設定

db/dbconf.yml
development:
  driver: mysql
  open: user=root dbname=goose_test

雑感

  • 普通な感じ
  • 使ってる人多そう
  • 適用履歴がテーブルに残るのは良い

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

$ goose create CreatePosts sql
goose: created /Users/nownabe/src/github.com/nownabe/research-go/migration-tools/goose/db/migrations/20170111152547_CreatePosts.sql

CLIで雛形を作成してそのファイルにUp/DownのSQLを書きます。

db/migrations/20170111152547_CreatePosts.sql
-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
CREATE TABLE `posts` (
  `post_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `author` VARCHAR(255) NOT NULL,
  `text` TEXT NOT NULL
) ENGINE = InnoDB;

-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back
DROP TABLE `posts`;

Golangでもマイグレーションファイル書けますが、あまり需要なさそうなので省略。

コマンド

$ goose
goose is a database migration management system for Go projects.

Usage:
    goose [options] <subcommand> [subcommand options]

Options:
  -env string
        which DB environment to use (default "development")
  -path string
        folder containing db info (default "db")
  -pgschema string
        which postgres-schema to migrate (default = none)

Commands:
    up         Migrate the DB to the most recent version available
    down       Roll back the version by 1
    redo       Re-run the latest migration
    status     dump the migration status for the current DB
    create     Create the scaffolding for a new migration
    dbversion  Print the current version of the database

バージョン管理

goose_db_versionというテーブルに保存されます。

> select * from goose_db_version;
+----+----------------+------------+---------------------+
| id | version_id     | is_applied | tstamp              |
+----+----------------+------------+---------------------+
|  1 |              0 |          1 | 2017-01-11 15:35:03 |
|  2 | 20170111152547 |          1 | 2017-01-11 15:47:34 |
|  3 | 20170111152547 |          0 | 2017-01-11 15:47:36 |
|  4 | 20170111152547 |          1 | 2017-01-11 15:47:36 |
|  5 | 20170111152547 |          0 | 2017-01-11 15:47:53 |
|  6 | 20170111152547 |          1 | 2017-01-11 15:48:06 |
+----+----------------+------------+---------------------+
6 rows in set (0.00 sec)

mattes/migrate

https://github.com/mattes/migrate

対応DB

  • Cassandra
  • MongoDB
  • MySQL (experimental)
  • PostgreSQL
  • SQLite
  • Ql

インストール

go get -u github.com/mattes/migrate

雑感

  • コマンドが豊富
  • CLIの結果が色付きで見やすい

スクリーンショット 2017-01-11 16.39.19.png (43.4 kB)

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

$ migrate -url="mysql://root@tcp(127.0.0.1:3306)/migrate_test" create create_posts
Version 1484119339 migration files created in /Users/nownabe/src/github.com/nownabe/research-go/migration-tools/goose:
1484119339_create_posts.up.sql
1484119339_create_posts.down.sql

CLIでUp/Downそれぞれの雛形ファイルが作成されます。

1484119339_create_posts.up.sql
CREATE TABLE `posts` (
  `post_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `author` VARCHAR(255) NOT NULL,
  `text` TEXT NOT NULL
) ENGINE = InnoDB;
1484119339_create_posts.down.sql
DROP TABLE `posts`;

コマンド

$ migrate
usage: migrate [-path=<path>] -url=<url> <command> [<args>]

Commands:
   create <name>  Create a new migration
   up             Apply all -up- migrations
   down           Apply all -down- migrations
   reset          Down followed by Up
   redo           Roll back most recent migration, then apply it again
   version        Show current migration version
   migrate <n>    Apply migrations -n|+n
   goto <v>       Migrate to version v
   help           Show this help

'-path' defaults to current working directory.

バージョン管理

schema_migrationsというテーブルに保存されます。

> select * from schema_migrations;
+------------+
| version    |
+------------+
| 1484119339 |
+------------+
1 row in set (0.00 sec)

rubenv/sql-migrate

https://github.com/rubenv/sql-migrate

対応DB

  • MySQL
  • MSSQL
  • Oracle Database
  • PostgreSQL
  • SQLite

インストール

go get github.com/rubenv/sql-migrate/...

設定

dbconfig.yml
development:
  dialect: mysql
  datasource: root:@tcp(127.0.0.1:3306)/sqlmigrate_test?parseTime=true
  dir: migrations/mysql # ディレクトリを作っておく必要がある

雑感

  • 対応RDBMSが多い

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

雛形作成機能はなし。

migrations/mysql/1_create_posts.sql
-- +migrate Up
-- SQL in section 'Up' is executed when this migration is applied
CREATE TABLE `posts` (
  `post_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `author` VARCHAR(255) NOT NULL,
  `text` TEXT NOT NULL
) ENGINE = InnoDB;

-- +migrate Down
-- SQL section 'Down' is executed when this migration is rolled back
DROP TABLE `posts`;

コマンド

$ sql-migrate
usage: sql-migrate [--version] [--help] <command> [<args>]

Available commands are:
    down      Undo a database migration
    redo      Reapply the last migration
    status    Show migration status
    up        Migrates the database to the most recent version available

バージョン管理

デフォルトでgorp_migrationsというテーブルに保存されます。

> select * from gorp_migrations;
+--------------------+---------------------+
| id                 | applied_at          |
+--------------------+---------------------+
| 1_create_posts.sql | 2017-01-11 08:12:18 |
+--------------------+---------------------+
1 row in set (0.00 sec)

elwinar/rambler

https://github.com/elwinar/rambler

対応DB

  • MySQL
  • PostgreSQL
  • SQLite

インストール

go get github.com/elwinar/rambler

設定

dbconfig.json
{
  "driver": "mysql",
  "protocol": "tcp",
  "host": "localhost",
  "port": 3306,
  "user": "root",
  "password": "",
  "database": "rambler_test",
  "directory": ".",
  "table": "migrations"
}

雑感

  • 設定ファイルがJSONで良い
  • ログがとても見にくい

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

雛形作成機能はなし。version_description.sqlという命名規則でファイルを作成します。

01_create_posts.sql
-- rambler up

CREATE TABLE `posts` (
  `post_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `author` VARCHAR(255) NOT NULL,
  `text` TEXT NOT NULL
) ENGINE = InnoDB;

-- rambler down

DROP TABLE `posts`;

コマンド

$ rambler
11:38 debug loading configuration from%!(EXTRA string=)unable to load configuration from file: open : no such file or directory

NAME:
   rambler - Migrate all the things!

USAGE:
   rambler [global options] command [command options] [arguments...]

AUTHOR:
   Romain Baugue <romain.baugue@elwinar.com>

COMMANDS:
     apply    apply the next migration
     reverse  reverse the last migration
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --configuration value, -c value  path to the configuration file
   --environment value, -e value    set the working environment (default: "default")
   --debug                          display debug messages
   --help, -h                       show help
   --version, -v                    print the version
unable to load configuration from file: open : no such file or directory

バージョン管理

> select * from migrations;
+---------------------+
| migration           |
+---------------------+
| 01_create_posts.sql |
+---------------------+
1 row in set (0.00 sec)

naoina/migu

https://github.com/naoina/migu

対応DB

  • MySQL

インストール

go get -u github.com/naoina/migu/cmd/migu

雑感

  • 細かいことを気にしなければ楽ちん
  • 融通はきかなそう

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

Goのstructを書きます。

schema.go
package main

type Post struct {
        PostId int `migu:"pk,autoincrement"`
        Author string
        Text   string `migu:"size:65535"`
}

マイグレーション

こんな感じでstructからスキーマを生成して実行してくれます。

$ migu sync -u root -h 127.0.0.1:3306 migu_test schema.go
--------applying--------
  CREATE TABLE `post` (
    `post_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `author` VARCHAR(255) NOT NULL,
    `text` MEDIUMTEXT NOT NULL
  )
--------done 0.019s--------

コマンド

$ migu
migu: too few arguments
Usage: migu [OPTIONS] COMMAND [ARG...]

Commands:
  sync      synchronize the database schema
  dump      dump the database schema as Go code

Options:
      --help             Display this help and exit

$ migu sync
migu: too few arguments
Usage: migu sync [OPTIONS] DATABASE [FILE]

Options:
      --dry-run          Print the results with no changes
  -q, --quiet            Suppress non-error messages
  -u, --user=NAME        User for login to database if not current user
  -h, --host=HOST        Connect to host of database
  -u, --user=NAME        User for login to database if not current user
  -p, --password[=PASS]  Password to use when connecting to server.
                         If password is not given, it's asked from the tty
      --help             Display this help and exit

With no FILE, or when FILE is -, read standard input.

dev-cloverlab/carpenter

https://github.com/dev-cloverlab/carpenter

対応DB

  • MySQL

インストール

go get github.com/dev-cloverlab/carpenter/cmd/carpenter

雑感

  • 面白い

スキーマエクスポート

carpenterは特殊なツールで、以下の2種類の操作ができます。

  • 実DBのスキーマをJSONへエクスポート
  • JSONのスキーマによるマイグレーション

JSONによるスキーマはかなり複雑で、人が書くものではなさそうです。

エクスポートは次のようなコマンドでできます。

carpenter --schema goose_test --data-source 'root:@tcp(127.0.0.1:3306)' design

tables.jsonというファイルが作成されます。

jq "." < tables.json | wc -l
     248
$ jq "." < tables.json | head -30
[
  {
    "TableCatalog": "def",
    "TableSchema": "goose_test",
    "TableName": "goose_db_version",
    "TableType": "BASE TABLE",
    "Engine": "InnoDB",
    "Version": 10,
    "RowFormat": "Compact",
    "TableRows": 14,
    "AvgRowLength": 1170,
    "DataLength": 16384,
    "MaxDataLength": 0,
    "IndexLength": 16384,
    "DataFree": 0,
    "AutoIncrement": 17,
    "TableCollation": "utf8_general_ci",
    "CheckSum": null,
    "CreateOptions": "",
    "TableComment": "",
    "Columns": [
      {
        "TableCatalog": "def",
        "TableSchema": "goose_test",
        "TableName": "goose_db_version",
        "ColumnName": "id",
        "OrdinalPosition": 1,
        "ColumnDefault": null,
        "Nullable": "NO",
        "DataType": "bigint",

マイグレーション

JSONがあれば、それをもとにテーブルを生成できます。

carpenter --schema carpenter_test --data-source 'root:@tcp(127.0.0.1:3306)' build --dir .

既にテーブルが存在してスキーマに変更があった場合はよろしくやってくれるようです。

コマンド

$ carpenter
NAME:
   carpenter - Carpenter is a tool to manage DB schema and data

USAGE:
   carpenter [global options] command [command options] [arguments...]

VERSION:
   0.3.1

AUTHOR:
   hatajoe <hatanaka@cloverlab.jp>

COMMANDS:
     design   Export table structure as JSON string
     build    Build(Migrate) table from specified JSON string
     import   Import CSV to table
     export   Export CSV to table
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --verbose, --vv                show verbose output (default off)
   --dry-run                      execute as dry-run mode (default off)
   --schema value, -s value       database name (required)
   --data-source value, -d value  data source name like '[username[:password]@][tcp[(address:port)]]' (required)
   --help, -h                     show help
   --version, -v                  print the version

CSVによるimport/exportもできるようです。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした