使用外键删除列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:refresh
或php artisan migrate:reset
将做的伎俩。