かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Grooy スクリプトをそのまま渡して実行する Spring Boot+Picocli ベースのコマンドラインアプリを作成する ( その3 )( サンプルの Groovy スクリプトをプロジェクト内に置く+PostgreSQL、MySQL を起動するための docker-compose.yml を作成してデータベース・テーブルを作成する )

概要

記事一覧はこちらです。

Grooy スクリプトをそのまま渡して実行する Spring Boot+Picocli ベースのコマンドラインアプリを作成する ( その2 )( groovy-script-executor.jar を作成する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • サンプルの Groovy スクリプトを置く場所を決めます。
    • サンプルの Groovy スクリプト で利用する PostgreSQLMySQL を起動するための docker-compose.yml を作成します。
    • PostgreSQL に sampledb、MySQL に testdb を作成します。
    • Flyway でテーブルを作成してデータを入れます。

参照したサイト・書籍

  1. Exclude file from jar using Gradle
    https://stackoverflow.com/questions/53394850/exclude-file-from-jar-using-gradle

  2. new collation (ja_JP.UTF-8) is incompatible with the collation of the template database (C)
    https://symfoware.blog.fc2.com/blog-entry-1737.html

  3. ロケール(国際化と地域化)
    https://lets.postgresql.jp/documents/technical/text-processing/2

  4. 国立国会図書館 - オープンデータセット
    https://www.ndl.go.jp/jp/dlib/standards/opendataset/index.html

目次

  1. groovy-script-executor/src/main/groovy の下に sample パッケージを作成し、その下にサンプルの Groovy スクリプトを置く
  2. サンプルの Groovy スクリプト で利用する PostgreSQL、MySQL を起動するための docker-compose.yml を作成する+PostgreSQL に sampledb、MySQL に testdb を作成する
  3. PostgreSQL の sampledb にテーブルを作成する
  4. MySQL の testdb にテーブルを作成する

手順

groovy-script-executor/src/main/groovy の下に sample パッケージを作成し、その下にサンプルの Groovy スクリプトを置く

groovy-script-executor/src/main/groovy の下にサンプルの Groovy スクリプトを置くと jar ファイルを作成した時にサンプルの Groovy スクリプトの class ファイルが入ってしまうと思っていたのですが、Exclude file from jar using Gradle のページを見つけて build.gradle に設定すれば jar ファイルに入らないようにできることが分かりました。

groovy-script-executor/src/main/groovy の下に sample パッケージを作成して、その下にサンプルの Groovy スクリプトを置くことにします。まずは Hello, World を出力する簡単な Groovy スクリプトを作成して動作確認する で作成した HelloWorld.groovy を置きます。

jar ファイル作成時に sample パッケージの下の *.groovy が入らないよう build.gradle に設定を追加します。

[compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8"
[compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"]
sourceSets {
    main {
        compileGroovy {
            exclude 'sample/*.groovy'
        }
    }
}
..........
  • sourceSets { ... } の設定を追加します。

sourceSets { ... } の設定がないと生成された jar ファイルの中に HelloWorld.class が入りますが、

f:id:ksby:20211029232710p:plain

sourceSets { ... } の設定があると入りません。

f:id:ksby:20211029233027p:plain

また groovy-script-executor/src/main/groovy/sample の下に置いた Groovy スクリプトは、クラス名か main メソッドの左側に表示されている矢印アイコンをクリックして表示される「Run 'HelloWorld.main()'」メニューを選択する(あるいは Ctrl+Shift+F10 を押す)ことで、

f:id:ksby:20211029234611p:plain

実行して結果を確認することが出来ます。

f:id:ksby:20211029234913p:plain

サンプルの Groovy スクリプト で利用する PostgreSQLMySQL を起動するための docker-compose.yml を作成する+PostgreSQL に sampledb、MySQL に testdb を作成する

プロジェクトの root ディレクトリ直下に .env を作成し、以下の内容を記述します。PostgreSQLMySQL のバージョンは AWS の Aurora でサポートされているバージョンにします(PostgreSQL は LTS の 11.9、MySQL は version 2 の 5.7)。

POSTGRESQL_VERSION=11.9
PGADMIN4_VERSION=6.1

MYSQL_VERSION=5.7.35
ADMINER_VERSION=4.8.1

PostgreSQL には sampledb、MySQL には testdb という名前のデータベースを作成します。

root ディレクトリ直下に docker/flyway/db/init ディレクトリを作成し(この次に Flyway でテーブルを作成するので docker/flyway ディレクトリの下に SQL ファイルを置いています)、その下に create_database_postgresql.sql を作成して以下の内容を記述します。

CREATE USER sampledb_user PASSWORD 'xxxxxxxx';
GRANT pg_read_server_files TO sampledb_user;
CREATE DATABASE sampledb OWNER sampledb_user ENCODING 'UTF8' LC_COLLATE 'ja_JP.UTF-8' LC_CTYPE 'ja_JP.UTF-8';

同じ場所に create_database_mysql.sql を作成して以下の内容を記述します。

create database if not exists testdb character set utf8mb4;

create user 'testdb_user'@'%' identified by 'xxxxxxxx';
grant all privileges ON testdb.* to 'testdb_user'@'%' with grant option;
grant select ON performance_schema.user_variables_by_thread to 'testdb_user'@'%';
flush privileges;

root ディレクトリ直下に docker-compose.yml を作成し、以下の内容を記述します。

# docker-compose build --no-cache
# docker-compose up -d
# docker-compose down
version: '3'

services:
  #############################################################################
  # PostgreSQL
  #
  postgresql:
    image: postgres:${POSTGRESQL_VERSION}-alpine
    container_name: postgresql
    ports:
      - "5432:5432"
    environment:
      - TZ=Asia/Tokyo
      - LANG=ja_JP.UTF-8
      - POSTGRES_PASSWORD=xxxxxxxx
    volumes:
      - ./docker/flyway/db/init/create_database_postgresql.sql:/docker-entrypoint-initdb.d/create_database.sql
      - ./docker/flyway/db/migration/postgresql_sampledb/jm2020.csv:/docker-entrypoint-initdb.d/jm2020.csv

  #############################################################################
  # pgAdmin 4
  #
  # URL
  # http://localhost:12000/
  pgadmin4:
    build:
      context: ./docker/pgadmin4
      args:
        - PGADMIN4_VERSION=${PGADMIN4_VERSION}
    image: dpage/pgadmin4:${PGADMIN4_VERSION}-custom
    container_name: pgadmin4
    ports:
      - "12000:80"
    environment:
      # TZ=Asia/Tokyo を設定してみたが日本時間に変わらなかったのでコメントアウトしておく
      # - TZ=Asia/Tokyo
      # PGADMIN_DEFAULT_EMAIL には接続する PostgreSQL の ユーザ名を設定する(サーバを追加する時楽なため)
      - PGADMIN_DEFAULT_EMAIL=postgres@example.com
      - PGADMIN_DEFAULT_PASSWORD=xxxxxxxx
      # PGADMIN_CONFIG_CONSOLE_LOG_LEVEL は debug 用
      # 設定値は https://www.pgadmin.org/docs/pgadmin4/development/config_py.html の CONSOLE_LOG_LEVEL 参照
      - PGADMIN_CONFIG_CONSOLE_LOG_LEVEL=10
      - PGADMIN_CONFIG_SESSION_DB_PATH='/var/lib/pgadmin_session'
    volumes:
      - ./docker/pgadmin4/data:/var/lib/pgadmin

  #############################################################################
  # MySQL
  #
  mysql:
    image: mysql:${MYSQL_VERSION}
    container_name: mysql
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - 3306:3306
    environment:
      - TZ=Asia/Tokyo
      - MYSQL_ROOT_PASSWORD=xxxxxxxx
    volumes:
      - ./docker/flyway/db/init/create_database_mysql.sql:/docker-entrypoint-initdb.d/create_database.sql

  #############################################################################
  # Adminer
  #
  # URL
  # http://localhost:13000/
  adminer:
    image: adminer:${ADMINER_VERSION}
    container_name: adminer
    ports:
      - 13000:8080
    environment:
      - TZ=Asia/Tokyo
      - ADMINER_DEFAULT_SERVER=mysql

docker-compose up -d コマンドを実行します。

f:id:ksby:20211030223058p:plain

http://localhost:12000/ にアクセス・ログインして pgAdmin 4 で sampledb が作成されていることを確認します。

f:id:ksby:20211030223432p:plain

http://localhost:13000/ にアクセス・ログインして Adminer で testdb が作成されていることを確認します。

f:id:ksby:20211030223646p:plain

docker-compose down コマンドを実行します。

PostgreSQL の sampledb にテーブルを作成する

国立国会図書館オープンデータセット の「国内刊行出版物の書誌情報 2020年分(tsv形式)」を取り込んだテーブルを作成します。

.env に FLYWAY_VERSION と sampledb に接続するための URL、USER、PASSWORD を記述します。

POSTGRESQL_VERSION=11.9
PGADMIN4_VERSION=6.1

MYSQL_VERSION=5.7.35
ADMINER_VERSION=4.8.1

FLYWAY_VERSION=8.0.2
SAMPLEDB_URL=jdbc:postgresql://postgresql/sampledb
SAMPLEDB_USER=sampledb_user
SAMPLEDB_PASSWORD=xxxxxxxx

docker/flyway/db の下に migration/postgresql_sampledb ディレクトリを作成し、その下に V1_0_0__create_publications.sql を作成して以下の内容を記述します。

create table publications
(
    id                bigserial constraint publications_pk primary key,
    url               text,
    fmt               text,
    book_number       text,
    isbm              text,
    issn              text,
    title_author      text,
    edition_indicates text,
    series            text,
    publication       text,
    remarks           text
);

docker-compose.yml の一番下に flyway_sampledb を追加します。

  ..........

  #############################################################################
  # Flyway for postgresql@sampledb
  #
  flyway_sampledb:
    image: flyway/flyway:${FLYWAY_VERSION}-alpine
    container_name: flyway_sampledb
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - ./docker/flyway/db/migration/postgresql_sampledb:/flyway/sql
    command: -url="${SAMPLEDB_URL}" -user=${SAMPLEDB_USER} -password=${SAMPLEDB_PASSWORD} -connectRetries=60 migrate
    depends_on:
      - postgresql
    # 下の3行は debug 用
    # うまく動かない時はコメントアウトを解除した後、
    # docker exec -it flyway_sampledb /bin/sh
    # で接続してから
    # flyway <command に記述した文字列>
    # を実行してみる
    #
    # entrypoint: /bin/sh
    # stdin_open: true
    # tty: true

docker-compose up -d コマンドを実行します。

IntelliJ IDEA の Database Tool Window を設定して publications テーブルが作成されていることを確認します。

f:id:ksby:20211031105032p:plain

国内刊行出版物の書誌情報(直近年1年分) から jm2020.txt をダウンロードし、Database Tool Window で import します。import できないデータが数十件出ますが、それらは無視します。

f:id:ksby:20211031110601p:plain f:id:ksby:20211031110715p:plain

データが import できたので今度は CSV ファイル(jm2020.csv)に export します。

f:id:ksby:20211031111952p:plain f:id:ksby:20211031112048p:plain

export した jm2020.csv を docker/flyway/db/migration/postgresql_sampledb の下に移動した後、docker-compose.yml を以下のように変更します。

  postgresql:
    image: postgres:${POSTGRESQL_VERSION}-alpine
    container_name: postgresql
    ports:
      - "5432:5432"
    environment:
      - TZ=Asia/Tokyo
      - LANG=ja_JP.UTF-8
      - POSTGRES_PASSWORD=xxxxxxxx
    volumes:
      - ./docker/flyway/db/init/create_database_postgresql.sql:/docker-entrypoint-initdb.d/create_database.sql
      - ./docker/flyway/db/migration/postgresql_sampledb/jm2020.csv:/docker-entrypoint-initdb.d/jm2020.csv
  • postgresql の volumes に - ./docker/flyway/db/migration/postgresql_sampledb/jm2020.csv:/docker-entrypoint-initdb.d/jm2020.csv を追加します。

docker/flyway/db/migration/postgresql_sampledb/V1_0_0__create_publications.sql を以下のように変更します。

create table publications
(
    ..........
);

COPY publications
FROM '/docker-entrypoint-initdb.d/jm2020.csv'
WITH CSV;

  • COPY publications FROM '/docker-entrypoint-initdb.d/jm2020.csv' WITH CSV; を追加します。

docker-compose downdocker-compose up -d コマンドを実行し、publications テーブルにデータが取り込まれることを確認します。

f:id:ksby:20211031113453p:plain

MySQL の testdb にテーブルを作成する

.env に testdb に接続するための URL、USER、PASSWORD を記述します。

..........

FLYWAY_VERSION=8.0.2
SAMPLEDB_URL=jdbc:postgresql://postgresql/sampledb
SAMPLEDB_USER=sampledb_user
SAMPLEDB_PASSWORD=xxxxxxxx
TESTDB_URL=jdbc:mysql://mysql:3306/testdb?sslMode=DISABLED&characterEncoding=utf8
TESTDB_USER=testdb_user
TESTDB_PASSWORD=xxxxxxxx

docker/flyway/db/migration の下に mysql_testdb ディレクトリを作成し、その下に V1_0_0__create_book.sql を作成して以下の内容を記述します。

create table book
(
    id     bigint auto_increment primary key,
    isbm   text null,
    title  text null,
    author text null
);

docker-compose.yml の一番下に flyway_testdb を追加します。

  ..........

  #############################################################################
  # Flyway for mysql@testdb
  #
  flyway_testdb:
    image: flyway/flyway:${FLYWAY_VERSION}-alpine
    container_name: flyway_testdb
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - ./docker/flyway/db/migration/mysql_testdb:/flyway/sql
    command: -url="${TESTDB_URL}" -user=${TESTDB_USER} -password=${TESTDB_PASSWORD} -connectRetries=60 migrate
    depends_on:
      - mysql
    # 下の3行は debug 用
    # うまく動かない時はコメントアウトを解除した後、
    # docker exec -it flyway_testdb /bin/sh
    # で接続してから
    # flyway <command に記述した文字列>
    # を実行してみる
    #
    # entrypoint: /bin/sh
    # stdin_open: true
    # tty: true

docker-compose downdocker-compose up -d コマンドを実行します。

IntelliJ IDEA の Database Tool Window を設定して book テーブルが作成されていることを確認します。。。が、作成されていませんね?

f:id:ksby:20211031114908p:plain

flyway_testdb コンテナのログを見ると ERROR: Flyway Teams Edition or MySQL upgrade required: MySQL 5.7 is no longer supported by Flyway Community Edition, but still supported by Flyway Teams Edition. のログが出力されていました。

f:id:ksby:20211031115110p:plain

Flyway のバージョンを 7 系の最新(7.15.0)に変更します。.env で FLYWAY_VERSION=8.0.2FLYWAY_VERSION=7.15.0 に変更します。

..........

FLYWAY_VERSION=7.15.0
SAMPLEDB_URL=jdbc:postgresql://postgresql/sampledb
SAMPLEDB_USER=sampledb_user
SAMPLEDB_PASSWORD=xxxxxxxx
TESTDB_URL=jdbc:mysql://mysql:3306/testdb?sslMode=DISABLED&characterEncoding=utf8
TESTDB_USER=testdb_user
TESTDB_PASSWORD=xxxxxxxx

docker-compose downdocker-compose up -d コマンドを実行すると今度は book テーブルが作成されました。MySQL 5.7 のサポートが終了したのは Flyway 8 からでした。

f:id:ksby:20211031115740p:plain

履歴

2021/10/31
初版発行。