在laravel中进行数据库迁移时,为表添加外键是一个常见操作。然而,不正确的写法可能会导致sqlstate[42s21]: column already exists: 1060 duplicate column name这样的错误,尤其是在执行php artisan migrate:fresh(该命令会删除所有表并重新运行所有迁移)时。
出现此错误的原因通常是开发者在迁移文件中对同一个外键列进行了重复定义。例如,在Laravel 8及更高版本中,foreignId()方法是一个非常便捷的工具,它不仅会创建对应的UNSIGNED BIGINT类型的列,还会自动添加外键约束。如果同时显式地定义了该列,就会造成重复。
错误示例代码:
考虑以下迁移代码片段,它试图为dso表添加一个指向rso表的id_rso外键:
public function up() { Schema::enableForeignKeyConstraints(); Schema::create('dso', function (Blueprint $table) { $table->string('id_dso',30); // 问题所在:此处显式定义了id_rso列 $table->unsignedBigInteger('id_rso'); // 再次定义id_rso列并添加外键约束,导致重复 $table->foreignId('id_rso')->constrained('rso'); $table->smallInteger('id_focus'); $table->smallInteger('id_wilayah'); $table->smallInteger('id_grup_wilayah'); $table->string('nama_dso',50); $table->string('created_by',50)->nullable(); $table->timestamp('created_date',$precision = 0); $table->string('modified_by',50)->nullable(); $table->timestamp('modified_date',$precision = 0)->nullable()->default(null); $table->boolean('status')->default(true); $table->timestamps(); $table->primary('id_dso'); }); }
在上述代码中,$table->unsignedBigInteger('id_rso'); 已经创建了一个名为id_rso的UNSIGNED BIGINT列。紧接着,$table->foreignId('id_rso')->constrained('rso'); 再次尝试创建同名的id_rso列,并将其类型设置为UNSIGNED BIGINT,同时添加了外键约束。这种重复操作导致了数据库抛出Duplicate column name 'id_rso'的错误。
解决这个问题的关键在于理解foreignId()方法的全部功能。它是一个复合方法,集成了列定义和外键约束的添加。因此,当使用foreignId()时,无需再单独声明列。
正确示例代码:
只需保留foreignId()这一行即可:
public function up() { Schema::enableForeignKeyConstraints(); // 确保外键约束已启用 Schema::create('dso', function (Blueprint $table) { $table->string('id_dso',30); // 正确用法:foreignId() 会自动创建 unsignedBigInteger 类型的列并添加外键约束 $table->foreignId('id_rso')->constrained('rso'); $table->smallInteger('id_focus'); $table->smallInteger('id_wilayah'); $table->smallInteger('id_grup_wilayah'); $table->string('nama_dso',50); $table->string('created_by',50)->nullable(); $table->timestamp('created_date',$precision = 0); $table->string('modified_by',50)->nullable(); $table->timestamp('modified_date',$precision = 0)->nullable()->default(null); $table->boolean('status')->default(true); $table->timestamps(); $table->primary('id_dso'); }); }
通过上述修改,id_rso列将只被创建一次,并且正确地附加了指向rso表的外键约束。
public function down() { Schema::table('dso', function (Blueprint $table) { $table->dropForeign(['id_rso']); // 删除外键约束 }); Schema::dropIfExists('dso'); // 删除表 }
遵循这些原则,可以有效避免Laravel迁移中常见的重复列和外键相关错误,确保数据库结构的稳定性和正确性。
以上就是解决Laravel迁移中外键重复列错误:正确使用foreignId的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号