Laravel5.x升级8迁移时regions表未生成state_id及外键不兼容问题
问题原因分析
第一次报错原因
- 你在regions表迁移中只定义了外键约束,没有先创建
state_id字段本身,$table->foreign()方法仅能给已存在的字段添加外键约束,不会自动生成对应字段,所以会报Key column 'state_id' doesn't exist in table错误。
第二次报错原因
- Laravel的
foreignId()方法默认创建的是无符号大整型(unsignedBigInteger)字段,而你的states表主键id是smallIncrements生成的无符号小整型(unsignedSmallInteger),两者类型不匹配,因此触发外键字段类型不兼容错误。
正确解决方案
两种方案按需选择即可:
方案1:保持states表原有主键类型不变
手动定义和states主键同类型的state_id字段,再添加外键约束,regions表迁移的对应代码修改为:
Schema::create('regions', function (Blueprint $table) { $table->smallIncrements('id')->unsigned(); // 先创建和states.id同类型的无符号小整数字段 $table->unsignedSmallInteger('state_id'); // 再给该字段加外键约束 $table->foreign('state_id') ->references('id') ->on('states') ->onUpdate('RESTRICT') ->onDelete('RESTRICT'); // 剩余原有代码保持不变 $table->string('name', 50); $table->string('slug', 55)->unique(); $table->enum('active', ['A', 'I'])->default('I')->comment(' A=>Active, I=>Inactive'); $table->unique(['state_id', 'name']); $table->index(['state_id', 'active'], 'fk_regions_state_id_active_ixd'); });
方案2:适配Laravel 8默认规范统一主键类型(推荐)
如果不需要兼容旧业务的smallint类型主键,可以将states表的主键修改为Laravel默认定义:
// states表迁移中的主键定义替换为以下代码 $table->id();
此时regions表的foreignId写法就可以正常运行:
$table->foreignId('state_id') ->constrained('states') ->onUpdate('RESTRICT') ->onDelete('RESTRICT');
内容的提问来源于stack exchange,提问作者Petro Gromovo
相关产品推荐
相关产品推荐

