【Laravel】昔作った5系のプロジェクトがマイグレート出来ない

2021年5月現在バージョンは8系ですので、新しくLaravelのプロジェクトを作る人にとっては意味がない情報かもしれません。

Installation - Laravel - The PHP Framework For Web Artisans


5系で動いているLaravelプロジェクトの環境構築する機会がありました。

現状で動いているプロジェクトなので動作は保証されているはずなのですが、環境構築時に手間取ってしまいました。
原因はマイグレーションです。

今回は、5系で環境構築時に発生したエラーと解決方法について記載します。

状況

2つのマイグレーションがあり、それぞれ次のような事をします。

  • テーブル作成
  • カラムの型変更

プロジェクトの初期構築は、3年位前と仮定します。

マイグレーションファイル

1つ目のマイグレーション:テーブルを作成

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateExamplesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('examples', function (Blueprint $table) {
            $table->string('value');
        });
    }
}

2つ目のマイグレーション:カラムの型を変更

カラムをvarchar からinteger に型を変更します

状況 キャラクターセット collation
変更前 varchar(255) utf8 utf8_unicode_ci
変更後 integer - -

マイグレーションは下記です。

<?php
// 2つ目のマイグレーション

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class Change ExamplesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('examples', function (Blueprint $table) {
            $table->integer('value')->change();
        });
    }
}

マイグレーション実行

この状態でマイグレーションを実行した所次のエラーが発生しました。

$ php artisan migrate
> Illuminate\Database\QueryException  : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHARACTER SET utf8 NOT NULL COLLATE `utf8_unicode_ci`, CHANGE value' at line 1 (SQL: ALTER TABLE examples CHANGE value value INT CHARACTER SET utf8 NOT NULL COLLATE `utf8_unicode_ci`)

Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHARACTER SET utf8 NOT NULL COLLATE utf8_unicode_ci, CHANGE value' at line 1 (SQL: ALTER TABLE examples CHANGE value value INT CHARACTER SET utf8 NOT NULL COLLATE utf8_unicode_ci)

失敗したクエリは下記です。

ALTER TABLE examples CHANGE value value INT CHARACTER SET utf8 NOT NULL COLLATE `utf8_unicode_ci`

原因

Laravelで使用しているDB用のモジュールがバージョンアップされた為です。
Laravelでデータベースのやりとりをするために、DBAL(database abstraction & access layer)というモジュールをラップして使っています。

github.com

旧環境はLaravel バージョン5.6で実装していましたが、その時のDBALはバージョン2.6でした。
(3系も出ていますが)2系の最新のバージョンは2.13です。

モジュール名 旧環境 アップデート後の環境
doctrine/dbal 2.6 2.13

DBALのバージョン2.9 以降の大きな仕様変更があったため、未来の仕様にフレームワーク側が対応しきれなかったようです。

stackoverflow.com

尚、Laravel 6系以降は対応されているので、このエラーは発生しません

このエラーは何を言いたいのか?

エラーを読む限りシンタックスエラーだと言うのがわかります。
これは、整数型(INT)なのにCHARACTER SETCOLLATEを設定するクエリを作ろうとしている為です。

INT型はそもそも文字コードがありません
その為、本来設定しないものを設定しようとしてエラーが発生しています。

解決方法

マイグレーションの解説ページに載っているSchema のバグですのでそのまま使う事はできません。
その為、型変更の処理を直接記述します。

readouble.com

<?php
// 2つ目のマイグレーション

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class Change ExamplesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // CHARACTER SET と COLLATE 省いたクエリにします。
        DB::statement('ALTER TABLE examples CHANGE value value INT');
    }
}


以上です。

前述しましたが、Laravel 6以降は解決されているエラーですのでそこまでクリティカルな問題ではないかもしれません。
ただ、昔作ったアプリケーションを引き継ぐ機会はあるかもしれません。

もし、Laravel 5系のマイグレーションを動かした時に同じようなエラーが出た場合は参考になさってください。

©︎2017-2018 WebSandBag