使用外键删除列Laravel错误:常规错误:1025重命名时出错

我用这样的迁移创build了一个表:

public function up() { Schema::create('despatch_discrepancies', function($table) { $table->increments('id')->unsigned(); $table->integer('pick_id')->unsigned(); $table->foreign('pick_id')->references('id')->on('picks'); $table->integer('pick_detail_id')->unsigned(); $table->foreign('pick_detail_id')->references('id')->on('pick_details'); $table->integer('original_qty')->unsigned(); $table->integer('shipped_qty')->unsigned(); }); } public function down() { Schema::drop('despatch_discrepancies'); } 

我需要改变这个表,并删除外键引用&列pick_detail_id并添加一个新的名为sku后面的pick_id列的varchar列。

所以,我创build了另一个迁移,看起来像这样:

 public function up() { Schema::table('despatch_discrepancies', function($table) { $table->dropForeign('pick_detail_id'); $table->dropColumn('pick_detail_id'); $table->string('sku', 20)->after('pick_id'); }); } public function down() { Schema::table('despatch_discrepancies', function($table) { $table->integer('pick_detail_id')->unsigned(); $table->foreign('pick_detail_id')->references('id')->on('pick_details'); $table->dropColumn('sku'); }); } 

当我运行这个迁移时,我得到以下错误:

[照亮\数据库\ QueryException]
SQLSTATE [HY000]:常规错误:1025将'./dev_iwms_reboot/despatch_discrepancies'重命名为'./dev_iwms_reboot/#sql2-67c-17c464'错误(错误:152)(SQL:alter table despatch_discrepancies drop foreign key pick_detail_id)

[PDOException]
SQLSTATE [HY000]:常规错误:1025将'./dev_iwms_reboot/despatch_discrepancies'重命名为'./dev_iwms_reboot/#sql2-67c-17c464'错误(错误:152)

当我尝试通过运行php artisan migrate:rollback命令来反转这个迁移时,我得到了一个Rolled back消息,但实际上并没有在数据库中做任何事情。

任何想法可能是错的? 如何删除具有外键引用的列?

你可以使用这个:

 $table->dropForeign(['pick_detail_id']); $table->dropColumn('pick_detail_id'); 

如果您在dropForeign源处取得峰值,那么如果您将列名作为数组传递,它将为您build立外键索引名称。

事实certificate, 当你像这样创build一个外键:

 $table->integer('pick_detail_id')->unsigned(); $table->foreign('pick_detail_id')->references('id')->on('pick_details'); 

Laravel唯一地命名这样的外键引用:

 <table_name>_<foreign_table_name>_<column_name>_foreign despatch_discrepancies_pick_detail_id_foreign (in my case) 

因此,当你想用外键引用删除一列时,你必须这样做:

 $table->dropForeign('despatch_discrepancies_pick_detail_id_foreign'); $table->dropColumn('pick_detail_id'); 

更新:

Laravel 4.2+引入了一个新的命名约定:

 <table_name>_<column_name>_foreign 

解决这个问题的关键是确保$ table-> dropForeign()命令传递正确的关系名称,而不一定是列名称。 你不想传递列名,因为会更直观恕我直言。

对我有效的是:

 $table->dropForeign('local_table_foreign_id_foreign'); $table->column('foreign_id'); 

所以我传递给我的dropForeign()的string格式为:

[本地表] _ [外键字段] _foreign

如果您有权使用像Sequel Pro或Navicat这样的工具,那么可以直观地看到这些工具将会非常有帮助。

传递一个col名的数组

 $table->dropForeign(['user_id']); 

发生在我身上的是我不知道把Schema::table块放在哪里。

后来我发现关键在于SQL错误:

 [Illuminate\Database\QueryException] SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table if exists `lu_benefits_categories`) 

因此, Schema::table块需要在lu_benefits_categories迁移的down()函数中以及Schema::dropIfExists行之前:

 public function down() { Schema::table('table', function (Blueprint $table) { $table->dropForeign('table_category_id_foreign'); $table->dropColumn('category_id'); }); Schema::dropIfExists('lu_benefits_categories'); } 

之后, php artisan migrate:refreshphp artisan migrate:reset将做的伎俩。