3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

sqldefで簡単にデータベーススキーマをマイグレーションする方法

Posted at

この記事はZOZO Advent Calendar 2024 シリーズ6 18日目の記事になります。

はじめに

sqldefについて調べたので、データベーススキーマをマイグレーションする方法をまとめてみました。

sqldefとは

sqldefは、データベースのスキーマを定義ファイルに基づいて自動的に更新するツールです。MySQL、PostgreSQL、SQLiteなど複数のデータベースをサポートしており、手動でスキーマを変更する手間を省き、バージョン管理されたスキーマ定義を簡単に適用できます。

プロジェクトのセットアップ

以下のコマンドでプロジェクトディレクトリと必要なサブディレクトリを作成します。

# プロジェクトディレクトリを作成
mkdir sqldef-example
cd sqldef-example

# 必要なディレクトリを作成
mkdir -p docker/sqldef database

Dockerfileの作成

docker/sqldef/Dockerfileを以下の内容で作成します。
Dockerfileではsqldefdockerizeをインストールし、エントリーポイントスクリプトを設定します。

# ベースイメージとしてAlpine Linuxを使用
FROM alpine

# 作業ディレクトリを設定
WORKDIR /tmp

# 必要なツールをインストール
RUN apk add --update --no-cache curl

# sqldefをダウンロードしてインストール
RUN curl -LO https://github.com/k0kubun/sqldef/releases/download/v0.17.24/mysqldef_linux_amd64.tar.gz && \
    tar xvf mysqldef_linux_amd64.tar.gz && \
    mv /tmp/mysqldef /usr/bin/mysqldef

# dockerizeをダウンロードしてインストール
RUN curl -L https://github.com/jwilder/dockerize/releases/download/v0.6.1/dockerize-alpine-linux-amd64-v0.6.1.tar.gz -o dockerize-alpine-linux-amd64.tar.gz && \
    tar xvf dockerize-alpine-linux-amd64.tar.gz && \
    mv /tmp/dockerize /usr/bin/dockerize

# エントリーポイントスクリプトをコピー
COPY docker/sqldef/entrypoint.sh /entrypoint.sh

# エントリーポイントスクリプトに実行権限を付与
RUN chmod +x /entrypoint.sh

# コンテナ起動時に実行するコマンドを設定
ENTRYPOINT ["/entrypoint.sh"]

スキーマ定義ファイルの作成

database/create_tables.sqlを以下の内容で作成します。
データベースに適用するスキーマ定義を記載します。

-- usersテーブルを作成
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

エントリーポイントスクリプトの作成

docker/sqldef/entrypoint.shを以下の内容で作成します。
このスクリプトはコンテナ起動時に実行され、MySQLが準備完了するのを待ってからsqldefを実行し、スキーマを適用します。

#!/bin/sh

# MySQLが準備完了するのを待つ
echo "Waiting for MySQL to be ready..."
dockerize -wait tcp://$MYSQL_HOST:$MYSQL_TCP_PORT -timeout 60s

# sqldefを実行してスキーマを適用
echo "Running sqldef..."
mysqldef --user=$MYSQL_USER --password=$MYSQL_PWD --host=$MYSQL_HOST $MYSQL_DATABASE < $SQL_FILE_TO_MIGRATE_APPLICATION_DATABASE

Docker Composeの設定

docker-compose.ymlをプロジェクトのルートディレクトリに以下の内容で作成します。
MySQLとアプリケーションのコンテナを定義し、環境変数を設定します。

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: sqldef-example-db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    ports:
      - "3306:3306"

  app:
    build:
      context: .
      dockerfile: docker/sqldef/Dockerfile
    environment:
      MYSQL_DATABASE: sqldef-example-db
      MYSQL_USER: user
      MYSQL_PWD: password
      MYSQL_HOST: mysql
      MYSQL_TCP_PORT: 3306
      SQL_FILE_TO_MIGRATE_APPLICATION_DATABASE: "/mysql/create_tables.sql"
    volumes:
      - ./database:/mysql

実行

以下のコマンドを実行してコンテナを起動し、マイグレーションを実行します。

docker-compose up

接続確認

以下のコマンドを実行して、MySQLクライアントを使用して接続します。

docker exec -it sqldef-example-mysql-1 mysql -u user -p

パスワードが求められたら、docker-compose.ymlで設定した MYSQL_PASSWORD (password) を入力します。

接続後、以下のコマンドを実行します。

SHOW DATABASES;
USE sqldef-example-db;
SHOW TABLES;
DESCRIBE users;

users テーブルが表示されれば、接続とスキーマの作成が成功しています。
これで、sqldefを使用したデータベーススキーマのマイグレーションが実行され、動作確認まで完了しました。

参考

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?