ダカーポとは
Laravelマイグレーションのサポートライブラリです。
データベースのテーブル定義をYAMLファイル(スキーマファイル)で管理し、マイグレーションファイルの生成を行います。
※初期の開発時期に利用されることを想定しています。
2021.01.11 v4.0.0 リリース!
2020.01.11 Laravel Dacapo v4.0 Released !https://t.co/qCFAAkaDtm #Laravel #PHP pic.twitter.com/VbbuFSNdAu
— ucan@Qiita新人賞 (@ucan_lab) January 11, 2021
v3.0から1年の時を経て、ついにバージョンv4.0をリリース致しました!🙇♂️
以前の古いコードをすべて破棄して新しく書き直してます。
少し挙動が異なる部分もあるのでこの機会に改めて使い方をご紹介します。
ダカーポ関連記事
以前のダカーポの記事
ダカーポの由来
ダ・カーポ(da capo)は音楽用語で「始めに戻って繰り返す」という意味があります。
PHPのパッケージ管理ツールであるComposerも作曲家という音楽用語であり、マイグレーションファイルをすべて削除して、最初から生成し直すことからピッタリな名前だなと思いました。
ダカーポを作った理由
デフォルトのマイグレーションのツラミ
- make:migration で自動生成された日付がバラバラで見にくい
- make:migration のコマンドの実行時間が遅い
- テーブル定義 → インデックス定義 → 外部キー制約の順に定義する手間
- ゴミマイグレーションが残る
- 最終的なテーブル構成はDBを直接見ないと把握しづらい
ダカーポの歴史
- 2018.11.06 v0.0.1 4files 初回リリース
- 2019.08.22 v1.0.0 22files 1ファイルで収まらなくなり、すべて書き直し
- 2019.08.22 v2.0.0 24files schema.ymlを分割可能、全カラムタイプに対応
- 2019.11.10 v3.0.0 35files 細々とバグFIXを続ける
- 2021.01.11 v4.0.0 144files メタプロでメンテしづらく、すべて書き直し
v1.0では4ファイルだけで書いてました...1日で主機能を書き上げたのでとてもFatなソースコードになってましたね。
それに比べて最新のv4.0ではファイル数が36倍に増えましたww
今後のバージョンアップに備えてLaravelでサポートされているカラムタイプやカラム修飾子をすべてクラスで管理するようにしました。
ダカーポのインストール
$ composer require --dev ucan-lab/laravel-dacapo
ダカーポの執筆時バージョン
- Dacapo: 4.0.1
ダカーポのサポート
- PHP 7.4 以降
- Laravel 6.x 以降
- MySQL
- PostgreSQL
- SQL Server(サポート対象外)
- SQLite(サポート対象外)
ダカーポの初期化
$ php artisan dacapo:init
dacapo:init
Artisanコマンドを使用して、ダカーポの初期化を行います。
database/schemas/default.yml
が生成されます。
また、database/migrations
ディレクトリ内のマイグレーションファイルも削除されます。
--no-clear オプション
$ php artisan dacapo:init --no-clear
database/migrations
ディレクトリ内のマイグレーションファイルの削除は行いません。
--laravel6, --laravel7 オプション
$ php artisan dacapo:init --laravel6
$ php artisan dacapo:init --laravel7
$ php artisan dacapo:init --laravel8 # default
それぞれLaravel6, Laravel7のマイグレーションファイルを生成します。
デフォルトでは、Laravel8のマイグレーションファイルを生成します。
それぞれのバージョンで微妙にテーブル定義内容が異なるので、テンプレートを分けています。
database/schemas/default.yml
database/schemas/default.yml
には、Laravelフレームワークにて予め用意されている(database/migrations)マイグレーション3ファイルのテーブルの定義しています。
users:
columns:
id:
name: string
email:
type: string
unique:
email_verified_at:
type: timestamp
nullable:
password: string
rememberToken:
timestamps:
password_resets:
columns:
email:
type: string
index:
token: string
created_at:
type: timestamp
nullable:
failed_jobs:
columns:
id:
uuid:
type: string
unique:
connection: text
queue: text
payload: longText
exception: longText
failed_at:
type: timestamp
useCurrent:
ダカーポの実行
$ php artisan dacapo
database/schemas/*.yml
からテーブル構成を読み込んで database/migrations/1970_01_01_*.php
のLaravelマイグレーションファイルを生成します。
また、ダカーポで生成された古いマイグレーションファイルはコマンド実行の都度削除されます。
続けて、 php artisan migrate:fresh
コマンドが実行されます。
すべてのテーブルの削除、及びマイグレーションの実行が行われます。
--seed オプション
$ php artisan dacapo --seed
php artisan migrate:fresh
に続けて
php artisan db:seed
コマンドが実行されます。
--no-migrate オプション
$ php artisan dacapo --no-migrate
スキーマファイルからマイグレーションファイルを実行したあと、 php artisan migrate:fresh
コマンドを実行しまいオプションです。
--refresh オプション
$ php artisan dacapo --refresh
ロールバック処理が動作するか、動作確認のためのオプションです。
スキーマの定義フォーマット
テーブル名:
columns:
カラム名: カラムタイプ
カラム名:
type: カラムタイプ
args: カラムタイプの引数(任意)
indexes:
- columns: [カラム名]
type: インデックス修飾子
name: インデックス名(任意)
foreign_keys:
- columns: [カラム名]
references: [カラム名]
table: テーブル名
- YAMLファイルは
database/schemas
ディレクトリに複数任意の名前で配置できます - YAMLファイル内に複数のテーブルを定義できます
スキーマの定義
カラムの定義
users:
columns:
# カラムタイプのみ指定する場合
votes: integer
# カラムタイプに引数を指定する場合
amount:
type: double
args: 8, 2
上記のYAMLを定義して php artisan dacapo
を実行すると、下記のマイグレーションファイルが出力されます。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->integer('votes');
$table->double('amount', 8, 2);
$table->string('email')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
利用可能なカラムタイプ
*.columns.*.type
に指定できるカラムタイプです。
Laravelマイグレーションで利用可能なカラムタイプはすべて対応してます。
bigIncrements, bigInteger, binary, boolean, char, dateTime, dateTimeTz, date, decimal, double, enum, float, foreignId, geometryCollection, geometry, id, increments, integer, ipAddress, jsonb, json, lineString, longText, macAddress, mediumIncrements, mediumInteger, mediumText, morphs, multiLineString, multiPoint, multiPolygon, nullableMorphs, nullableTimestamps, nullableUuidMorphs, point, polygon, rememberToken, set, smallIncrements, smallInteger, softDeletes, softDeletesTz, string, text, timestamps, timestampsTz, timestamp, timestampTz, time, timeTz, tinyIncrements, tinyInteger, unsignedBigInteger, unsignedDecimal, unsignedInteger, unsignedMediumInteger, unsignedSmallInteger, unsignedTinyInteger, uuidMorphs, uuid, year
カラム修飾子
上記リストのカラムタイプに加え、データベーステーブルにカラムを追加するときに使用できるカラム「修飾子」もあります。
users:
columns:
email:
type: string
nullable: true
上記のYAMLを定義して php artisan dacapo
を実行すると、下記のマイグレーションファイルが出力されます。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->string('email')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
利用可能なカラム修飾子
alwaysModifier, autoIncrementModifier, charsetModifier, collationModifier, commentModifier, defaultModifier, defaultRawModifier, fromModifier, generatedAsModifier, indexModifier, nullableModifier, storedAsModifier, uniqueModifier, unsignedModifier, useCurrentModifier, useCurrentOnUpdateModifier, virtualAsModifier
利用不可なカラム修飾子
下記のカラム修飾子はダカーポではサポート対象外となっております。
after, change, first, renameColumn, dropColumn, dropMorphs, dropRememberToken, dropSoftDeletes, dropSoftDeletesTz, dropTimestamps, dropTimestampsTz, constrained, onUpdate, onDelete
インデックス修飾子
users:
columns:
id: bigIncrements
name: string
email: string
indexes:
- columns: [name, email]
type: index
name: users_name_index
- 1970_01_01_000001_create_users_table.php
- 1970_01_01_000002_create_users_index.php
- インデックスの定義ファイルは
000002
のプレフィックスが付きます。
- インデックスの定義ファイルは
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersIndex extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->index(['name', 'email'], 'users_name_index');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropIndex('users_name_index');
});
}
}
利用可能なインデックス修飾子
primary, unique, index, spatialIndex
外部キー制約
users:
columns:
id: bigIncrements
name: string
email: string
posts:
columns:
id: bigIncrements
user_id: unsignedBigInteger
content: string
foreign_keys:
- columns: [user_id]
references: [id]
table: users
- 1970_01_01_000001_create_users_table.php
- 1970_01_01_000001_create_posts_table.php
- 1970_01_01_000003_constraint_posts_foreign_key.php
- 外部キーの定義ファイルは
000003
のプレフィックスが付きます。
- 外部キーの定義ファイルは
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('content');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class ConstraintPostsForeignKey extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('posts', function (Blueprint $table) {
$table->foreign(['user_id'])->references(['id'])->on('users');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('posts', function (Blueprint $table) {
$table->dropForeign(['user_id']);
});
}
}
その他
通常のマイグレーションファイルと併用可能
$ php artisan make:migration create_flights_table
php artisan dacapo
で database/migrations
ディレクトリ内のマイグレーションファイルが削除されますが、
ダカーポで生成されたファイルのみ削除されます。(1970_01_01
のプレフィックスが付いたファイルのみ)
YAMLで表現できないようなテーブル定義は通常のマイグレーションファイルを作成してください。
複数のスキーマファイルを利用可能
database/schemas/*.yml
ファイルを読み込むので、YAMLを分けて定義できます。
database/schemas/user.yml
database/schemas/staff.yml
ユーザー関連のテーブル、スタッフ関連のテーブル等、グループ分けをしてテーブルを定義していくこともできます。
今後の予定
ざっくり今後のダカーポについて検討していることを書きます。
あくまで予定で、全機能実装できるかは未定です...。
v4.0
年末年始に一気に書き殴ったので、しばらくはリファクタリングに勤しみます。
新機能 v4.1
dacapo --mixin オプション
SQLiteは外部キー制約を書く場合は、テーブル定義と同じタイミングで実行する必要があるみたいです。
懸念点としては、制約を貼る順番によってはエラーになりそうなので生成順序を気にしないといけなさそう...🤔
難しそうなのでこのオプションの実装悩んでます。。
dacapo --squash オプション
Laravel8に搭載されたマイグレーションスカッシングのイメージです。
ただ、mysqldump
コマンド入れてる必要があったり、.sql
ファイルで出力されちゃったりと不満があります。
--squash
オプションは1ファイルのマイグレーションファイルにまとめるオプションです。
これは需要ありそうかなと思ってるんですけどどうでしょうか?🤔
新機能 v4.2
テンプレート生成するコマンド
$ php artisan dacapo:generate:model
$ php artisan dacapo:generate:factory
$ php artisan dacapo:generate:seeder
$ php artisan dacapo:generate:validation
スキーマYAMLから各種テンプレートを生成する機能です。
v3系には合ったのですが、バージョンアップの兼ね合いで一旦コマンドを削除しました。
v4.0系でも実装しようと思ったのですが、
Laravel8でモデルファクトリ書き方が丸っと変わったのでちょっと断念しました。
新機能 v4.3
データベースからスキーマYAMLを逆生成するコマンド
$ php artisan dacapo:db:import
この機能が欲しくてv4.0の書き直しをしたので、なんとしてでもこの機能は実装する!
新機能 v4.4
データベースとスキーマYAMLの差分からマイグレーションを生成するコマンド
$ php artisan dacapo:db:diff
import
コマンドが実装できたら現行のテーブル構成とスキーマYAMLの差分ができたらいいなと思ってます。
これは実装難しそうなので悩んでます。