spring-boot
Flyway

Spring Boot + Flywayでコードによるデータベースマイグレーション

Spring BootでFlywayを使ってマイグレーションを行なっているのですが、初期データをCSVから加工して投入したいことがあったので、コードによるマイグレーションを試してみました。

Java-based migrations

Java-based migrationsのページに書いてある手順で、CSVを取り込んで加工するJavaクラスを作成します。

マイグレーション用のJavaクラス作成

src/main/java配下にdb.migration配下にこちらのページに書いてある命名形式でクラスを作成します。
基本的にマイグレーション用のSQLの命名規則と同じです。

作成したクラスにJdbcMigrationもしくはSpringJdbcMigrationを継承します。
今回はSpring Bootを使用しているので、SpringJdbcMigrationを継承し、migrateメソッドを実装します。

V1__add_test_user.java
package db.migration;

import org.flywaydb.core.api.migration.spring.SpringJdbcMigration;
import org.springframework.jdbc.core.JdbcTemplate;

public class V1__add_test_user implements SpringJdbcMigration {
    public void migrate(JdbcTemplate jdbcTemplate) throws Exception {
        jdbcTemplate.execute("INSERT INTO test_user (name) VALUES ('テストユーザ')");
    }
}

データベースへの投入は引数で渡ってくるJdbcTemplateを使用してデータ投入等のSQLを実行します。
今回の例では固定でSQLを実行していますが、CSVからデータを読み込んでデータ投入などSQLだけだと難しいデータ投入がコードによるマイグレーションを使うことでできるかと思います。

おまけ:CSVファイルの読み込みとデータ投入

V2__insert_word_positive_negative.java
package db.migration;

import org.flywaydb.core.api.migration.spring.SpringJdbcMigration;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class V2__insert_word_positive_negative implements SpringJdbcMigration {

    @Override
    public void migrate(JdbcTemplate jdbcTemplate) throws Exception {
        try(BufferedReader br = new BufferedReader(
                new InputStreamReader(getClass().getClassLoader().getResourceAsStream("db/migration/seed/pn.csv.m3.120408.trim")))) {

            String str;
            while ((str = br.readLine()) != null) {
                String[] split = str.split("\t"); // タブで分割
                if (split.length > 1) {

                    String emotion = split[1].trim(); // p or e or n
                    int score = 0;
                    if (emotion.equals("p")) {
                        score = 1;
                    } else if (emotion.equals("n")) {
                        score = -1;
                    }
                    jdbcTemplate.update("REPLACE INTO WordPositiveNegative(word, score) VALUES (?,?)",split[0].trim(),score);
                }
            }
        }
    }
}

今回のサンプルでは東北大学の乾・岡崎研究室が公開している日本語評価極性辞書をsrc/main/resources/db/migration/seed配下に置いてます。