You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 01:05:19