今回は上記のような方に向けて、マイグレーションであれこれする方法について紹介していきます。
Laravel8でマイグレーションを行う方法
以下のマイグレーションパターンについて、それぞれ解説していきます。
※目次と押すとジャンプします
①テーブルの作成/削除
まず、テーブルの作成、削除の方法です。
以下コマンドでマイグレーションファイルを作成します。
php artisan make:migration create_テーブル名_table
作成したファイルに、以下のように記述します。
public function up()
{
Schema::create('テーブル名', function (Blueprint $table) {
$table->id(); //id
$table->string('name'); //名前
//$table->string('name')->nullable(); nullを許可する場合
//他にも追加したいカラムがあったら足す。制約も好きにつけることができる
});
}
public function down()
{
Schema::drop('テーブル名');
}
作成時のコマンド(マイグレーション実行時のコマンド)
php artisan migrate
削除時のコマンド
php artisan migrate:rollback
ちなみに、作成時に、カラムタイプや制約を指定することも当然可能です。
カラムタイプ(intやstring)については、利用可能なカラムタイプを参考にできます。
②カラムの追加/削除
次に、カラムの追加及び削除の方法です。
以下のコマンドを叩いて、マイグレーションファイルを作成しましょう。
php artisan make:migration add_user_id_to_comments_table
このとき「--table = comments」でテーブル名を指定することを指示しているブログなどがあります。
が、これはなくても大丈夫です。
マイグレーションファイル名で「to_テーブル名」にしておけば、Laravelがよしなに対象テーブルを判断してくれます。
作成したファイルの中身に、以下のように追加メソッドを入れていきます。
public function up()
{
Schema::table('commentss', function (Blueprint $table) {
$table->integer('user_id'); //カラム追加
});
}
public function down()
{
Schema::table('posts', function (Blueprint $table) {
$table->dropColumn('user_id'); //カラムの削除
});
}
ちなみに、カラムタイプ(intやstring)については、利用可能なカラムタイプを参考にできます。
また、制約もかけることができます。
例えば、以下のような感じです。
Schema::table('commentss', function (Blueprint $table) {
$table->integer('user_id')->nullable(); //カラム追加&null許可制約
});
Laravelには、マイグレーションファイルで使える便利なカラム修飾子が用意されています。
null許可、デフォルト値の設定、主キーなどを設定したい場合は使いましょう。
以下、いくつか使用例を載せておきます。
修飾子 | 説明 |
after('column') | 続くカラムを指定 |
autoIncrement() | 自動採番 |
charset('utf8mb4') | 文字セット |
collation('utf8mb4_unicode_ci') | 照合順序 |
comment('コメント') | コメント |
default('デフォルト値') | デフォルト値 |
first() | 最初のカラム |
nullable() | null許可 |
nullable(fakse) | null不許可 |
unsigned() | UNSIGNED |
useCurrent() | CURRENT _TIMESTAMPを デフォルト値 |
useCurrentOnUpdate() | 更新時に CURRENT _TIMESTAMPを 指定する |
参考:公式ドキュメント
✔ 削除時
削除時は以下のコマンドを実行しましょう。
php artisan migrate:rollback
こちらを実行することで、マイグレーションファイルのdownメソッド(削除処理)が走ります。
先程の例だと「$table->dropColumn('user_id'); 」のとこですね。
ただし、上記のコマンドは直近に作成されたマイグレーションファイルしか実行されません。
例えば、Aというマイグレーションを実行した後に、Bというマイグレーションを実行したとします。
その後にrollbackのコマンドを叩いても、削除対象になるのは「B」のマイグレーションだということです。
Aまで含めたい場合は、以下のコマンドを叩く必要があります。
php artisan migrate:rollback --step=2 //最後の2つをロールバック
ロールバックが無事できたかどうかは、マイグレーションテーブルを見ればわかります。
DBに「migrations」というテーブルがあるので、そちらを以下のコマンドで確かめておきましょう。
SELECT * FROM DB名.migrations;
ロールバックしたマイグレーションが、物理削除されていれば成功です。
ちなみにmigrationsテーブルの「batch」カラムは、マイグレーションを行った順番になります。
複数同時にマイグレーションを実行した場合は、複数のマイグレーションファイルに同じbatchの値がつくというわけです。
これらは、ロールバックの際に「同一」としてみなされるので、注意しておきましょう。
(つまり、A、B、Cの3つのマイグレーションを実行後にロールバックすると、3つとも消えるということ)
✔ 補足:複数カラムの削除も可能
複数のカラムも、1つのメソッドで削除できます。
配列で、カラムを指定してあげればOKです。
具体的には以下の通り。
$table->dropColumn(['votes', 'avatar', 'location']);
この場合、「votes」「avatar」「location」カラムが削除されます。
③カラムの変更
次にカラムの変更時のマイグレーションについて解説します。
以下のコマンドでマイグレーションファイルを作成します。
php artisan make:migration change_id_to_admins_table
こちらも「to_テーブル名_table」でLaravel側がテーブルを指定したマイグレーションファイルを作ってくれます。
作成したファイルにメソッドを書いていきます。
public function up()
{
Schema::table('admins', function (Blueprint $table) {
$table->smallInteger('id')->change(); //型をsamllintに変更
});
}
public function down()
{
Schema::table('admins', function (Blueprint $table) {
$table->integer('id')->change(); //型をintに変更(ロールバック用)
});
}
上記を最初に実行しようとすると、次のエラーで怒られます。
Changing columns for table "admins" requires Doctrine DBAL. Please install the doctrine/dbal package
なので、最初にdoctrine/dbal
パッケージをインストールしておきましょう。
次のコマンドを実行しておいてください。
composer require doctrine/dbal
再度、php artisan migrateで実行してみるとうまくいくはずです。
✔ 補足:対応していないカラムの型があります
ちなみになのですが、型変換の際にLaravelがサポートしていない型を指定すると、失敗します。
例えば、tinyIntegerはサポートされていません。
次のようなエラーが出ます。
Unknown column type "tinyinteger" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database introspection then you might have forgotten to register all database types for a Doctrine Type. Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMappedDatabaseTypes(). If the type name is empty you might have a problem with the cache or forgot some mapping information.
公式ドキュメントにも、サポートされているタイプについては説明されています。
Note: 以降のカラムタイプを変更できます。
bigInteger
、binary
、boolean
、date
、dateTime
、dateTimeTz
、decimal
、integer
、json
、longText
、mediumText
、smallInteger
、string
、text
、time
、unsignedBigInteger
、unsignedInteger
、unsignedSmallInteger
、uuid
。
ということで、サポート外の型にしたい場合は、直にSQL文を書きましょう。
次のような感じです。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
class ChangeIdToAdminsTable extends Migration
{
public function up()
{
Schema::table('admins', function (Blueprint $table) {
DB::statement('ALTER TABLE `laravel`.`admins`
CHANGE COLUMN `id` `id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT');
});
}
public function down()
{
Schema::table('admins', function (Blueprint $table) {
$table->integer('id')->change();
});
}
}
✔ カラムの制約変更
カラムの型ではなく、制約を変更したい場合も似たような感じになります。
具体的には以下のとおりです。
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('name')->nullable(false)->change();
$table->rememberToken()->nullable(false)->default('0')->change();
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->string('name')->change();
$table->rememberToken()->change();
});
}
制約を変更して、change()を指定してあげればOKですね。
✔ カラムの名前変更
カラムの名前を変更したい場合は、次のように記述します。
Schema::table('テーブル名', function (Blueprint $table) {
$table->renameColumn('変える前の名前', '変えた後の名前');
});
以上がカラム追加、削除などの変更系の処理です。
④インデックスの追加/削除
最後に、インデックスの追加と削除です。
以下のコマンドでマイグレーションファイルを作成しましょう。
php artisan make:migration add_name_index_to_users_table
作成されたファイルに以下のように記述します。
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->index(['name']); //インデックス追加
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropIndex(['name']); //インデックス削除
});
}
あとは、作成時に「php artisan migrate」、削除時に「php artisan migrate:rollback」を実行すればOKです。
✔ 複合インデックスの場合
複合インデックスの場合は、対象カラムを配列で渡しつつ、インデックス名を指定してあげればOKです。
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->index(['id', 'title'], 'users_id_title'); //users_id_titleという名前の複合インデックスができる
});
}
public function down()
{
Schema::table('expert_profiles', function (Blueprint $table) {
$table->dropIndex('users_id_title'); //インデックス名を文字列で渡せばOK
});
}
ということで、以上①テーブルの作成/削除、②カラムの追加/削除、③カラムの変更、④インデックスの追加/削除でした。