自己紹介
- ucan-lab(ゆうきゃん)
- 株式会社ROLO所属
- https://qiita.com/ucan-lab
- PHP/Laravel エンジニア
- エンジニア歴13年くらい
- 組み込み→アプリ→ウェブ
動画
Laravel Dacapoのソースコード
ご紹介するライブラリのGitHubリポジトリです。
スター数が少ないとライブラリとしての信用度が上がらずなかなか使ってくれる人が増えないのでよければスターしてもらえると嬉しいです。
Laravel マイグレーションとは
- データベースのテーブル定義の変更履歴を管理する
- データベースのテーブル定義をSQLではなくPHPファイルで管理できる
- 特定のデータベースに依存しない(MySQL, PostgreSQL, SQL Server, SQLite)
- 別の環境でも同じテーブル構成をコマンド一発で反映できる
利用ツール
- Visual Studio Code(VSCode)
- Sequel Ace
- https://sequel-ace.com
- MySQLクライアントツール
実行環境
- Mac: 11.6.2
- Docker: 20.10.10
- PHP: 8.1.3
- Laravel: 9.5.1
- https://qiita.com/ucan-lab/items/6a3481b389a886115ada
- 補足: Laravel9からLaravel Sanctumが標準搭載されています。話がややこしくなるので今回は無効化してます。
- 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');
}
};
-
up
とdown
の2つのメソッドを用意する -
up
には新しいテーブル、カラム、インデックス、外部キーの追加等 -
down
はup
と対になるコードを書きます。
$ 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