LoginSignup
6
1

More than 1 year has passed since last update.

Laravel Dacapo マイグレーションサポートツール

Last updated at Posted at 2022-05-06

自己紹介

  • ucan-lab(ゆうきゃん)
  • 株式会社ROLO所属
  • https://qiita.com/ucan-lab
  • PHP/Laravel エンジニア
  • エンジニア歴13年くらい
  • 組み込み→アプリ→ウェブ

動画

Laravel Dacapoのソースコード

ご紹介するライブラリのGitHubリポジトリです。

スター数が少ないとライブラリとしての信用度が上がらずなかなか使ってくれる人が増えないのでよければスターしてもらえると嬉しいです。

Laravel マイグレーションとは

  • データベースのテーブル定義の変更履歴を管理する
  • データベースのテーブル定義をSQLではなくPHPファイルで管理できる
  • 特定のデータベースに依存しない(MySQL, PostgreSQL, SQL Server, SQLite)
  • 別の環境でも同じテーブル構成をコマンド一発で反映できる

利用ツール

実行環境

  • Mac: 11.6.2
  • Docker: 20.10.10
  • PHP: 8.1.3
  • Laravel: 9.5.1
  • Laravel Dacapo: 5.1.2

通常のマイグレーションファイルの作成手順

$ php artisan make:migration create_flights_table

database/migrations/2022_03_15_144938_create_flights_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * マイグレーションの実行
     *
     * @return void
     */
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    /**
     * マイグレーションを戻す
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('flights');
    }
};
  • updown の2つのメソッドを用意する
  • up には新しいテーブル、カラム、インデックス、外部キーの追加等
  • downup と対になるコードを書きます。
$ php artisan migrate

マイグレーションファイルを適用します。

Laravel マイグレーションのツラミ

  • 開発中はテーブル定義がしょっちゅう変わる
  • 30〜40行にもなるphpクラスを書く必要がある
  • インデックスや外部キー制約を貼る順番を意識する必要がある
  • マイグレーションファイルだけでは最新のテーブル定義がわからない

Laravel Dacapoの特徴

  • YAMLでテーブル定義を管理する
  • テーブル定義の一覧性が向上する
  • YAMLから常に最新のマイグレーションファイルが生成される
  • 毎回テーブルの中身がクリアされる
  • 開発中のみ使用される想定のライブラリ

インストール手順

$ composer require --dev ucan-lab/laravel-dacapo
$ php artisan dacapo:init

database/schemas/default.yml にファイルが生成されます。

$ php artisan dacapo

database/migrations にマイグレーションファイルが生成されます。

スキーマYAMLフォーマット

テーブル名:
  comment: テーブルコメント
  columns:
    カラム名: カラムタイプ
    カラム名:
      type: カラムタイプ
      args: カラムタイプの引数(任意)
      カラム修飾子: カラム修飾子の引数
    エイリアスカラムタイプ:

  indexes:
    - columns: [カラム名]
      type: インデックス修飾子
      name: インデックス名(任意)

  foreign_keys:
    - columns: [カラム名]
      references: [カラム名]
      table: テーブル名

試しにいくつかテーブル定義する

例としてヨガ予約サイトのテーブル定義をしています。

  • members(会員テーブル)
  • instructors(インストラクターテーブル)
  • lessons(レッスンテーブル)
  • stores(店舗テーブル)
  • studios(スタジオテーブル)
  • reserved_lessons(予約済みレッスンテーブル)
  • canceled_lessons(予約済みレッスンテーブル)
  • completed_lessons(完了済みレッスンテーブル)

8つのテーブルを定義します。
関連のあるテーブルに外部キー制約を付けていきます。

members:
  comment: 会員テーブル
  columns:
    id:
    name: string
    email:
      type: string
      unique:
    email_verified_at:
      type: timestamp
      nullable:
    password: string
    rememberToken:
    timestamps:

instructors:
  comment: インストラクターテーブル
  columns:
    id:
    name: string

lessons:
  comment: レッスンテーブル
  columns:
    id:
    instructor_id: unsignedBigInteger
    studio_id: unsignedBigInteger
    name: string
    capacity:
      type: unsignedInteger
      comment: 最大参加人数
    strength:
      type: string
      comment: 強度
    started_at:
      type: dateTime
      comment: 開始日時
    minutes:
      type: unsignedInteger
      comment: レッスン時間(分)
    timestamps:
  indexes:
    - columns: started_at
      type: index
  foreign_keys:
    - columns: instructor_id
      references: id
      table: instructors
    - columns: studio_id
      references: id
      table: studios

stores:
  comment: 店舗
  columns:
    id:
    name: string
    address: string
    phone_number: string
    timestamps:

studios:
  comment: スタジオ
  columns:
    id:
    store_id: unsignedBigInteger
    name: string
    timestamps:
  foreign_keys:
    - columns: store_id
      references: id
      table: stores

reserved_lessons:
  comment: 予約済みレッスンテーブル
  columns:
    id:
    member_id: unsignedBigInteger
    lesson_id: unsignedBigInteger
    timestamps:
  foreign_keys:
    - columns: member_id
      references: id
      table: members
    - columns: lesson_id
      references: id
      table: lessons

canceled_lessons:
  comment: キャンセル済みレッスンテーブル
  columns:
    id:
    member_id: unsignedBigInteger
    lesson_id: unsignedBigInteger
    timestamps:
  foreign_keys:
    - columns: member_id
      references: id
      table: members
    - columns: lesson_id
      references: id
      table: lessons

completed_lessons:
  comment: 完了済みレッスンテーブル
  columns:
    id:
    member_id: unsignedBigInteger
    lesson_id: unsignedBigInteger
    timestamps:
  foreign_keys:
    - columns: member_id
      references: id
      table: members
    - columns: lesson_id
      references: id
      table: lessons

YAML定義をしたらダカーポコマンドを実行します。

$ php artisan dacapo

スキーマフォーマットの補足

テーブル名:
  columns:
    comment: テーブルコメント
    カラム名: カラムタイプ
    カラム名:
      type: カラムタイプ
      args: カラムタイプの引数(任意)
      カラム修飾子: カラム修飾子の引数
    エイリアスカラムタイプ:

  indexes:
    - columns: [カラム名]
      type: インデックス修飾子
      name: インデックス名(任意)

  foreign_keys:
    - columns: [カラム名]
      references: [カラム名]
      table: テーブル名

利用可能なカラムタイプ

テーブル名.columns.カラム名.type で利用可能なカラムタイプの一覧です。

https://readouble.com/laravel/9.x/ja/migrations.html#available-column-types

利用可能なカラム修飾子

テーブル名.columns.カラム名.カラム修飾子 で利用可能なカラムタイプの一覧です。

https://readouble.com/laravel/9.x/ja/migrations.html#column-modifiers

利用可能なインデックス修飾子

テーブル名.indexes.*.type: インデックス修飾子 で利用可能なインデックス修飾子の一覧です。

https://readouble.com/laravel/9.x/ja/migrations.html#available-index-types

YAMLで表現できない複雑な例

複雑なマイグレーションを書きたい場合もあります。
通常のマイグレーションファイルと共存できます。

https://readouble.com/laravel/9.x/ja/migrations.html#default-expressions

$ php artisan make:migration create_flights_table
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Migrations\Migration;

return new class extends Migration
{
    /**
     * マイグレーションの実行
     *
     * @return void
     */
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->json('movies')->default(new Expression('(JSON_ARRAY())'));
            $table->timestamps();
        });
    }

    /**
     * マイグレーションを戻す
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('flights');
    }
};
$ php artisan dacapo

手動で作成したマイグレーションファイルは削除されずに実行されています。

アンインストール手順

ダカーポはDBクリアする前提で使用するため、運用フェーズに入ったらアンインストールします。

$ php artisan dacapo:uninstall
$ composer remove ucan-lab/laravel-dacapo
6
1
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
6
1