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

flywayでMySQLのテーブルを管理する(入門)

概要

  • MySQLのDDLの管理がしたくなったのでflywayを使ってみる
  • 一応現場でも使用することを想定してパスワードの直打ちやファイルに記載してGitに上がってしまうことがないように意識してみています
  • flywayコマンドの実行結果は可視性の向上のために説明に必要な部分のみ記載します

環境やバージョン

  • windows
  • MySQL 5.7 (ローカル)
  • flyway 4.2.0

参考

Flywayのインストール

まずはflywayのインストールから

ここからZipファイルを取得し、解凍。

今回は1から必要なファイル等を把握していきたいので
flyway-<version>配下の「flyway」と「flyway.cmd」のみをPathの通ったディレクトリに配置する

<PATH>
 └ flyway
 └ flyway.cmd

MySQLの構築

ダウンロード

  • ここからダウンロード
  • 上のweb版の方をダウンロードしましたが特にやりにくい感じではなくインストールを進められました

接続

インストール時に設定したパスワードを用いて接続します

>mysql -u root -p
Enter password: *****

データベースの作成

Flywayでは接続情報としてDBまでは必要になるため、
事前に作成しておきます

create database sample;

この記事では実施をしませんが、実際に運用する際は必要な権限のみを持ったユーザーを作成してrootユーザーでflywayを実行することはしないなと思います。

Flywayの設定~疎通確認

任意のディレクトリで設定ファイルを作成していきます

conf/flyway.conf
flyway.url=jdbc:mysql://localhost:3306/sample
flyway.user=root
#flyway.password=

flyway.locations=filesystem:sql/

パスワードは以下のようにユーザー入力によって設定します

windows
>set /P FLYWAY_PASSWORD="flyway.password: "
flyway.password: *****
mac
$ echo -n "flyway.password: "; read FLYWAY_PASSWORD
flyway.password: *****

ここまでできたら疎通確認をしてみます

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+-------------+---------------------+---------+
| Version | Description | Installed on        | State   |
+---------+-------------+---------------------+---------+
| No migrations found                                   |
+---------+-------------+---------------------+---------+

macの場合は変数の読込が${FLYWAY_PASSWORD}となるはずです。

ドキュメントを見る限り、環境変数に設定するだけで使用可能なように見えるのですが、うまくできなかったので実行時引数で渡していますmm

Flywayの使い方

SQL作成

ここからSQLを書いていきます。

SQLファイルは形式が決まっておりV<version>__<description>.sqlという形式で作成します。

今回はversion=1.0.0で作成してみます
1, 1.0といったバージョンも可です

あくまで参考に…ですが、僕だったらこのように使い分けます
major version: ユーザー追加等のDB管理に関する変更時
minor version: テーブルやインデックスの追加・更新等の通常変更時
patch version: minor versionを上げたあとの軽微な修正

V1.0.0__create_sample_table.sql
create table sample (
  id varchar(10) primary key,
  name varchar(10)
);

状態確認

疎通確認時のコマンドと一緒です
infoコマンドを使用します

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+---------------------+---------------------+---------+
| Version | Description         | Installed on        | State   |
+---------+---------------------+---------------------+---------+
| 1.0.0   | create sample table |                     | Pending |
+---------+---------------------+---------------------+---------+

ファイル名からVersionとDescriptionが抽出され、Statusには現在のSQLの実行状態が表示されます。

SQL実行前は「Pending」となっています。

反映

migrateコマンドを使用します

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% migrate

Migrating schema `sample` to version 1.0.0 - create sample table
Successfully applied 1 migration to schema `sample` (execution time 00:00.118s).

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+---------------------+---------------------+---------+
| Version | Description         | Installed on        | State   |
+---------+---------------------+---------------------+---------+
| 1.0.0   | create sample table | 2020-09-02 21:27:34 | Success |
+---------+---------------------+---------------------+---------+

正常にSQLが実行できるとStateが「Success」となります!

ベースラインの設定

例えば、途中までは手動でSQLを実行していたけれども、これからはFlywayでSQL管理したいといったケースを考えてみます。

sql
 └ V1.0.0__create_sample_table.sql  ← 手動で実行していたSQL
 └ V2.0.0__add_column_to_sample_table.sql  ← このSQLからFlywayで管理したい

V1.0.0のSQLがすでにflyway以外の方法で実行されていた場合、各コマンドは以下のような結果になります。

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+----------------------------+---------------------+---------+
| Version | Description                | Installed on        | State   |
+---------+----------------------------+---------------------+---------+
| 1.0.0   | create sample table        |                     | Pending |
| 2.0.0   | add column to sample table |                     | Pending |
+---------+----------------------------+---------------------+---------+

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% migrate

ERROR: Found non-empty schema(s) `sample` without metadata table! Use baseline() or set baselineOnMigrate to true to initialize the metadata table.

baselineを使ってねと出力されているので、baselineを設定してみます。
baselineコマンドとbaselineVersionオプションを使用します

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% -baselineVersion=1.0.0 baseline

Creating Metadata table: `sample`.`schema_version`
Successfully baselined schema with version: 1.0.0

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+----------------------------+---------------------+---------+
| Version | Description                | Installed on        | State   |
+---------+----------------------------+---------------------+---------+
| 1.0.0   | << Flyway Baseline >>      | 2020-09-02 22:37:49 | Success |
| 2.0.0   | add column to sample table |                     | Pending |
+---------+----------------------------+---------------------+---------+

すると、1.0.0がSuccessとなり、migrateも通るようになります!

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% migrate

Migrating schema `sample` to version 2.0.0 - add column to sample table
Successfully applied 1 migration to schema `sample` (execution time 00:00.060s).

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+----------------------------+---------------------+---------+
| Version | Description                | Installed on        | State   |
+---------+----------------------------+---------------------+---------+
| 1.0.0   | << Flyway Baseline >>      | 2020-09-02 22:37:49 | Success |
| 2.0.0   | add column to sample table | 2020-09-02 22:40:32 | Success |
+---------+----------------------------+---------------------+---------+

migrateに失敗したとき

例えばSQLの構文エラーがあったりすると以下のようにStateがFailedになる

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+---------------------+---------------------+---------+
| Version | Description         | Installed on        | State   |
+---------+---------------------+---------------------+---------+
| 1.0.0   | create sample table | 2020-09-02 23:03:19 | Failed  |
+---------+---------------------+---------------------+---------+

このようなときはSQLを修正し、repairコマンドを実行し、migrate前の状態に復元。
その後再度migrateコマンドを実行する。

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% repair

Successfully repaired metadata table `sample`.`schema_version` (execution time 00:00.032s).
Manual cleanup of the remaining effects the failed migration may still be required.

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+---------------------+---------------------+---------+
| Version | Description         | Installed on        | State   |
+---------+---------------------+---------------------+---------+
| 1.0.0   | create sample table |                     | Pending |
+---------+---------------------+---------------------+---------+

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% migrate

Migrating schema `sample` to version 1.0.0 - create sample table
Successfully applied 1 migration to schema `sample` (execution time 00:00.044s).

>flyway -configFile=conf\flyway.config -password=%FLYWAY_PASSWORD% info

+---------+---------------------+---------------------+---------+
| Version | Description         | Installed on        | State   |
+---------+---------------------+---------------------+---------+
| 1.0.0   | create sample table | 2020-09-02 23:17:02 | Success |
+---------+---------------------+---------------------+---------+

補足:repairコマンドの動作

repairコマンドで実行されるのは、version管理用のテーブルにおいて、Stateが「Failed」のものを「Pending」に戻すだけです。
そのため、以下のようなSQLファイルを実行し、2つめのSQLで失敗した場合は1つ目のSQLの結果を手動で戻してあげる必要があります

sample.sql
create table sample1 (
  hoge varchar(10) primary key
);

create table sample2 (
  hoge text primary key
);

この場合だとdrop table sample1;を手動実行してあげるが必要あります。
ちなみにFlywayのmetadataは「schema_version」という自動で作成されるテーブルで管理されています。

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
ユーザーは見つかりませんでした