Laravel迁移报errno:150「外键约束格式不正确」错误如何解决?
错误原因
- 缺失目标字段:首次创建
user_information表的代码中未定义register_type_id字段,更新迁移中直接对不存在的字段调用change()方法,会导致字段修改逻辑整体失效,后续外键创建时字段类型不符合要求。 - 字段类型不匹配:外键字段的类型必须和关联表主键的类型完全一致。若关联表(如
profession等)的主键使用increments('id')(对应无符号整型unsignedInteger),你在更新迁移中将外键改为unsignedBigInteger,两者类型不一致,无法创建约束。 - 字段修改未生效:Laravel中使用
change()方法修改字段属性需要依赖doctrine/dbal扩展包,未安装该包时,change()语句不会实际修改数据库中的字段类型,外键字段仍为初始定义的integer类型,和关联表主键不匹配。 - 关联信息拼写错误:若关联表实际名称和外键定义中填写的表名不一致(比如Laravel默认表名为复数,你未手动指定关联表单数表名的话,
profession对应实际表名应为professions),也会触发该报错。
解决方案
- 补全缺失字段:在更新迁移的字段修改逻辑最前面,先添加不存在的
register_type_id字段,不要直接调用change()方法:
Schema::table('user_information', function (Blueprint $table){ // 先添加缺失的字段 $table->unsignedBigInteger('register_type_id')->nullable(); // 再修改其他已有字段的类型 $table->unsignedBigInteger('user_id')->change(); $table->unsignedBigInteger('profession_id')->change(); $table->unsignedBigInteger('country_id')->change(); $table->unsignedBigInteger('company_id')->nullable()->change(); $table->unsignedBigInteger('social_network_id')->nullable()->change(); // 外键创建逻辑保持不变 $table->foreign('user_id')->references('id')->on('users'); $table->foreign('profession_id')->references('id')->on('profession'); $table->foreign('country_id')->references('id')->on('country'); $table->foreign('company_id')->references('id')->on('company'); $table->foreign('social_network_id')->references('id')->on('social_network'); $table->foreign('register_type_id')->references('id')->on('register_type'); });
- 统一字段类型:先确认所有关联表的主键类型,和外键字段保持完全一致:
- 若关联表主键为
increments('id'),将外键字段改为unsignedInteger()->change() - 若关联表主键为
bigIncrements('id')或id(),外键字段保持unsignedBigInteger()即可
- 若关联表主键为
- 安装字段修改依赖:在项目根目录执行以下命令安装
doctrine/dbal扩展包,保证change()方法生效:
composer require doctrine/dbal
- 校验关联信息:确认所有外键定义中的关联表名、主键字段名和实际数据库中的表结构完全一致。
- (可选优化)本地开发无历史数据的情况下,可以直接修改初始建表迁移,一次性定义好正确的字段类型和外键,避免分两次迁移出现兼容性问题。
内容的提问来源于stack exchange,提问作者Paul Antonio Portugal Herencia
相关产品推荐
相关产品推荐

