Laravel执行迁移报1005错误:外键约束错误无法创建employees表
问题原因及解决方案
1. 修复迁移执行顺序
Laravel 迁移按照文件名前缀的时间戳从小到大执行,你当前的依赖关系为:payments 依赖 employees,employees 依赖 departments,因此必须保证三个迁移的时间戳顺序为:departments 迁移最早,其次是 employees,最后是 payments。如果顺序错误,创建带外键的表时依赖的表还未生成,就会触发150报错。
2. 修复外键引用字段的约束要求
外键引用的目标字段必须满足「是主键/有唯一约束」、「字段类型完全匹配」两个要求,现有代码存在两处不符合要求的问题:
- departments 表的
name字段作为被外键引用的目标,没有添加唯一约束,修改 departments 迁移代码:
public function up() { Schema::create('departments', function (Blueprint $table) { $table->id(); // 替换原有的bigInteger('id'),默认就是unsignedBigInteger类型的自增主键 $table->string('name')->unique(); // 新增唯一约束 $table->timestamps(); }); }
- 所有表的 id 字段都需要设置为主键自增,你当前只定义了 id 的字段类型,没有添加主键属性,同时 departments、payments 表的 id 为
bigInteger类型,和关联字段的unsignedBigInteger类型不匹配,修改对应表的 id 定义:
// employees表的id定义修改为 $table->id(); // payments表的id定义修改为 $table->id();
3. 优化外键定义逻辑
不要在表创建的闭包内直接定义外键,统一在表创建完成后单独添加,避免偶发的表未创建完成就加外键的报错,以 employees 表为例修改为:
public function up() { Schema::create('employees', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('department'); $table->string('location'); $table->string('telephone'); $table->decimal('salary',16); $table->string('cover_image'); $table->timestamps(); }); // 单独添加外键 Schema::table('employees', function (Blueprint $table) { $table->foreign('department')->references('name')->on('departments')->onUpdate('cascade')->onDelete('cascade'); }); }
4. 重新执行迁移
修改完成后本地开发环境可以执行以下命令重置迁移:
php artisan migrate:fresh
如果是生产环境不能清空数据,可以先回滚到迁移前的状态,再重新执行迁移。
内容的提问来源于stack exchange,提问作者Mohammad Reza Rezaei
相关产品推荐
相关产品推荐

