環境
- Laravel 5.7.28
- MySQL 8.0.17
遭遇した問題
DBの容量を節約するため、既存カラムのデータ型をintからtinyintに変更するマーグレーションを実行した際、下記のようなエラーが表示された。
「tinyintegerなんてカラム型はないよ」と怒られているので、「あ、マイグレーションファイルにtinyIntegerではなくtinyintegerとタイピングしちゃったかな」なんて思って確認してみるも、間違っていない。
ちなみにマイグレーションファイルの中身は以下のような感じです。
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class ChangeContactTypeOfUsers extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->tinyInteger('contact_type')->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->integer('contact_type')->change();
});
}
}
原因
Laravel公式ドキュメントのMigrationの項を当たってみると、以下の通り。
Only the following column types can be "changed"
の部分を和訳すると、「以下のカラムの型のみが変更可能です」となります。
試してみたところ、tinyintから別の型に変更することはできましたが、逆にtinyintには変更できませんでした。
つまり、Laravelではカラムの型をtinyintに変更することはできないということです。
また、例えばtinyintからintに変更するマイグレーションが通ったとしても、ロールバック時にはコケるので、tinyint型のカラムの型変更は行わないほうがよいでしょう。
tinyintに変更することで、格納可能サイズを超過するデータが生じる恐れがあるため、このような仕様となっているのでしょうか。
詳しい方いらっしゃいましたらコメントにてご教授いただけると幸いです。
対処法
一旦該当カラムをドロップし、再度tinyint型として追加することで対処しました(この時点では未使用のカラムだったので)。
結局、型変更のために2つのマイグレーションファイルの作成が必要になってしまいました。
※2019/12/4 追記
職場の方にご指摘いただき気付いたのですが、DBファサードを利用してSQLクエリを実行すれば解決する問題でした。
DB::statement("alter table users modify tel_type tinyint;");
学び
テーブルを作成する際には、格納され得るデータを予め想定し、適切にデータ型を決定する必要があるということを学習しました。