laravel

Laravel8でマイグレーションを行う方法【カラム追加/削除・カラム変更・インデックス追加/削除など】

2021年8月3日

ジェンガで遊ぶ少年

 

あなた
Laravel8でマイグレーションを行う方法を知りたいです。

 

今回は上記のような方に向けて、マイグレーションであれこれする方法について紹介していきます。

 

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: 以降のカラムタイプを変更できます。bigIntegerbinarybooleandatedateTimedateTimeTzdecimalintegerjsonlongTextmediumTextsmallIntegerstringtexttimeunsignedBigIntegerunsignedIntegerunsignedSmallIntegeruuid

 

ということで、サポート外の型にしたい場合は、直に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
        });
    }

 

ということで、以上①テーブルの作成/削除、②カラムの追加/削除、③カラムの変更、④インデックスの追加/削除でした。

 

-laravel

© 2021 エンジニアてんし君ブログ