Laravel 9切换至MySQL后关联表迁移失败求助
Laravel 关联表迁移报错(SQLite转MySQL)
问题核心原因
报错根源是外键字段类型与主表主键不匹配:
- 主表
test1s和test2s通过$table->id()创建的主键,在MySQL中对应类型为unsigned bigint - 关联表
test1s_test2s里的test1_id、test2_id被定义为string类型,MySQL对外键约束的类型匹配要求严格,因此触发errno:150错误。而SQLite对类型校验宽松,所以本地开发阶段未暴露问题。
你之前尝试给主键加->unsigned()无效,是因为字段本身的string类型和主表主键的unsigned bigint完全不兼容,必须先修正字段类型。
解决方法
修改关联表的迁移代码,将外键字段类型改为与主表主键一致的unsignedBigInteger,或使用Laravel提供的简化语法foreignId:
方案1:显式指定字段类型
public function up() { Schema::create('test1s_test2s', function (Blueprint $table) { // 定义与主表主键匹配的字段类型 $table->unsignedBigInteger('test1_id'); $table->unsignedBigInteger('test2_id'); // 设置复合主键 $table->primary(['test1_id', 'test2_id']); // 配置外键约束 $table->foreign('test1_id') ->references('id') ->on('test1s') ->onDelete('cascade'); $table->foreign('test2_id') ->references('id') ->on('test2s') ->onDelete('cascade'); }); }
方案2:使用Laravel简化语法(推荐)
foreignId()会自动创建unsigned bigint类型的字段,constrained()自动关联对应表的主键,代码更简洁:
public function up() { Schema::create('test1s_test2s', function (Blueprint $table) { $table->foreignId('test1_id') ->constrained('test1s') ->onDelete('cascade'); $table->foreignId('test2_id') ->constrained('test2s') ->onDelete('cascade'); $table->primary(['test1_id', 'test2_id']); }); }
额外注意事项
- 确保主表
test1s和test2s的迁移文件在关联表迁移之前执行(文件名前缀的时间戳更早),否则MySQL会因主表不存在报错。 - 如果已执行过错误的迁移,需先回滚(
php artisan migrate:rollback)再重新执行迁移。
内容的提问来源于stack exchange,提问作者Ja Nosch
相关产品推荐
相关产品推荐

