Laravel5.2 マイグレーション

DDLを書いていた頃が懐かしい。。。今はマイグレーションを使ってテーブル構造もバージョン管理するようになりました。
ローカルにDBがある場合は気軽にできるかもしれませんが、DBを共有している場合は慎重に行うことには今も昔も変わりません。
ということで、前回からの流れでマイグレーションがどのように動くのか見てみます。
クライアント環境:Windows10 XAMPP(PHP7.0.4) Eclipse 4.5.2(Mars) Laravel5.2.33
サーバ環境:CentOS7 MariaDB5.5.47

マイグレーション

・実行

>php artisan migrate
「database/migrations」にある実行されていないものが古い順に全て実行される。
※リビジョン?バージョン?情報は「migrations」テーブルにある。
・ロールバック(リビジョン?バージョン?を1つ戻す)
>php artisan migrate:rollback
※「migrations」テーブルにあるbatchが一番大きいクラスを全て実行する感じ。
・リセット(初期状態に戻す)
>php artisan migrate:reset
※ただし、再度マイグレーションすると「migrations」テーブルのbatchは全て1になるので、rollbackは初期状態に戻す形となる。
・再マイグレーション(初期状態に戻してマイグレーション実行)
>php artisan migrate:refresh
「–seed」オプションが有る時は「/database/seeds/DatabaseSeeder.php」の初期データが投入される。追加したSeederは読み込まれないのか、他にも設定があるのかわからない。
・マイグレーションで”class not found”エラーが出る場合
>composer dump-autoload
上記を実行して再度マイグレーションするとよいかもしれない。

テーブルの追加

マイグレーション用クラスの準備
>php artisan make:migration <<クラス名>> --create=<<テーブル名>>
「database/migrations」にファイルが追加される。
クラス名は他と重複しないようにする。(マイグレーションのロールバックでエラーになります。)
命名基準としては以下の感じがよいかな。。。
<<create|alter|drop>>_<<テーブル名>>_<<YYYYMMDD>>_table
追加されたファイルの内容(tasksテーブルの例)
<?php
 
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
 
class CreateTasksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }
 
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tasks');
    }
}

マイグレーション実行時にupメソッドが呼ばれて、rollbackでdownメソッドが呼ばれる。

テーブルにコメントを設定したいけど、どうするのかな。。。
普通にクエリー発行してコメントをつけるのなら、「Schema::create」の後に
「ALTER TABLE tasks comment=”コメント名”」をDB::statementで実行するぐらいしか思いつかない・・・

列の追加

コマンドプロンプト

>php artisan make:migration <<クラス名>> --table=<<テーブル名>>
追加されたファイルにnameカラムを追加(tasksテーブルの例)
<?php
 
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
 
class AlterTasksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('tasks', function (Blueprint $table) {
            $table->string("name", 100)
                //->first()        // カラムを先頭に持ってくる
                ->nullable()    // NULLを許容
                ->after('id')    // カラムの場所をIDカラムの後ろに
                ->comment('タスク名')    // 列名のコメント
                ->default('うにうに')    // デフォルト値
                //->unsigned()    // 符号なしに。
                ;
         });
    }
 
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('tasks', function (Blueprint $table) {
            $table->dropColumn("name");
        });
    }
}

これで、nameカラムが追加され、rollbackするとnameカラムが削除される。

列の場所も変更できるし、列にコメントを設定できるしいい感じ。

列の変更

    public function up()
    {
        Schema::table('tasks', function (Blueprint $table) {
            $table->string('name', 200)->change();
        });
    }

マイグレーションを実行するとエラーとなる。

  [RuntimeException]
  Changing columns for table "tasks" requires Doctrine DBAL; install "doctrin
  e/dbal".
DBALが必要なのね・・・
「composer.json」をいじる
   "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.2.*",
        "doctrine/dbal": ">=2.0"     ← 追加(どのバージョンが良いかは不明・・・)
    },
コマンドプロンプトで「composer update」(ちょっと時間かかる)
>composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Removing laravel/framework (v5.2.32)
  - Installing laravel/framework (v5.2.33)
    Downloading: 100%
 
  - Removing mockery/mockery (0.9.4)
  - Installing mockery/mockery (0.9.5)
    Downloading: 100%
 
  - Installing doctrine/lexer (v1.0.1)
    Downloading: 100%
 
  - Installing doctrine/annotations (v1.2.7)
    Downloading: 100%
 
  - Installing doctrine/collections (v1.3.0)
    Downloading: 100%
 
  - Installing doctrine/cache (v1.6.0)
    Downloading: 100%
 
  - Installing doctrine/common (v2.6.1)
    Downloading: 100%
 
  - Installing doctrine/dbal (v2.5.4)
    Downloading: 100%
 
Writing lock file
Generating autoload files
Warning: Ambiguous class resolution, "AlterTasksTable" was found in both "D:/xampp7.0.4/htdocs/laravel_trial/database/migrations/2016_05_25_075114_alter_tasks_table.php" and "D:/xampp7.0.4/htdocs/laravel_trial/database/migrations/2016_05_26_022139_alter_tasks_table.php", the first will be used.
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize
Generating optimized class loader

あら?ワーニングが出る…同名のクラスをだとロールバックやらマイグレーションで戻せなくなる。クラス名の命名基準で、作成日時を入れるとか必要かと。

気を取り直して再度マイグレーションすると、列名の変更ができた。
参考)

インデックス、プライマリキー、外部キー

省略・・・(気が向いたら後日・・・)

初期データ

参照)
コマンドプロンプト
>php artisan make:seeder TasksTableSeeder
「/database/seeds/TasksTableSeeder.php」ができる。
<?php
 
use Illuminate\Database\Seeder;
 
class TasksTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // サンプルで、100件をtasksテーブルに投入する。
        for($i = 0; $i < 100; $i++) {
            DB::table('tasks')->insert([
                'name' => 'task_name' . $i,
            ]);
        }
    }
}
モデルを使う方法とかいろいろとあるので、その時に応じて作成。
コマンドプロンプトで初期データを投入する
>php artisan db:seed --class=TasksTableSeeder
負荷試験用のデータ準備とかで便利だ。
マイグレーションについて戯れてみましたが、実際の開発でとなるといろいろとルールの整備がかなり必要かなぁと思う。