🙌
MySQLコンテナの初回起動時にテーブルを作成してCSVデータをインポートする
やること
表題の通り、MySQLコンテナの初回起動時にテーブルを作成し、初期データをCSVからインポートします。
ディレクトリ構成
ルートディレクトリでdocker-compose up -d
すればMySQLコンテナが立ち上がり、初期データがインポートされます。
.
├── docker-compose.yml
├── .env
└── docker
└── mysql
├── Dockerfile
├── my.cnf
└── initdb.d
├── 0_create_db.sql
├── 1_create_table.sql
├── 2_import_inital_data.sql
└── initial-data
└── data.csv
コンテナの基本設定
docker-compose.yml
./docker-compose.yml
version: '3'
services:
mysql:
container_name: mysql8
build:
context: ./docker/mysql
volumes:
- db-store:/var/lib/mysql
environment:
- MYSQL_DATABASE=${DB_DATABASE}
- MYSQL_USER=${DB_USERNAME}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
- TZ=${APP_TZ:-Asia/Tokyo}
ports:
- ${DOCKER_DB_PORT:-3306}:3306
volumes:
db-store:
./.env
DOCKER_DB_PORT=3306
DB_DATABASE=test_db
DB_USERNAME=dev_user
DB_PASSWORD=password
APP_TZ=Asia/Tokyo
CSVデータのインポートを許可する
LOAD DATA INFILE
を使うとCSVデータをインポートすることができます。
ただし、MySQL8.0ではデフォルトでCSVのインポートは禁止されており、サーバ側[mysqld]
とクライアント側[mysql]
の両方で明示的に許可する必要があります。参照
./docker/mysql/my.cnf
[mysql]
local-infile=1
[mysqld]
local-infile=1
ここで、クライアント側のオプショングループは、クライアント[client]
ではなく、コマンドラインクライアント[mysql]
であることに注意が必要です。参照
MySQLコンテナの初回起動時にSQLを実行する
MySQLコンテナの初回起動時に/docker-entrypoint-initdb.d
に配置したSQLが実行されます。参照
SQLファイルが複数ある場合、名前順に実行されますので、数字をプレフィックスとして付けておくと良いかもしれません。
2回目以降のコンテナ起動ではvolumeを削除しないとSQLが実行されませんのでご注意ください。参照
./docker/mysql/Dockerfile
FROM mysql:8
# MySQL設定ファイルをコピー
COPY my.cnf /etc/mysql/conf.d/my.cnf
# データ初期化用SQLファイルコピー
COPY ./initdb.d /docker-entrypoint-initdb.d
EXPOSE 3306
初期データをインポートするSQLサンプル
./docker/mysql/initdb.d/0_create_db.sql
DROP SCHEMA IF EXISTS test_db;
CREATE SCHEMA test_db;
USE test_db;
./docker/mysql/initdb.d/1_create_table.sql
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` enum('M','F') NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (emp_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC
./docker/mysql/initdb.d/2_import_inital_data.sql
load data local infile
"/docker-entrypoint-initdb.d/intial-data/data.csv " // コンテナ側のpathを指定
into table employees fields terminated by ',' optionally enclosed by '"'
ignore 1 lines; // 2行目からインポート
Discussion