带外键的删除列 Laravel 错误: 常见错误: 重命名时出现1025错误

我使用如下迁移创建了一个表:

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,并在 pick_id列之后添加一个名为 sku的新 varchar 列。

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

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');
});
}

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

[照明数据库查询异常]
SQLSTATE [ HY000] : 常见错误: 重命名为 ’./dev _ iwms _ reboot/despatch _ different’到 ’./dev _ iwms _ reboot/# sql2-67c-17c464’(errno: 152)(SQL: alter table despatch_discrepancies删除外键 pick _ Details _ id)

[ PDOException ]
SQLSTATE [ HY000] : 常见错误: 重命名为 ’./dev _ iwms _ reboot/despatch _ different’到 ’./dev _ iwms _ reboot/# sql2-67c-17c464’(errno: 152)

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

知道哪里出错了吗? 如何删除具有外键引用的列?

154587 次浏览

结果是,当你创建一个像这样的外键:

$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

更新:

Larave > 8.x 引入了一个新函数

dropConstrainedForeignId('pick_detail_id');

这将删除该列以及该列的外键

你可以用这个:

Schema::table('despatch_discrepancies', function (Blueprint $table) {
$table->dropForeign(['pick_detail_id']);
$table->dropColumn('pick_detail_id');
});

如果您在 dropForeign 源处获取一个峰值,那么如果将列名作为数组传递,它将为您构建外键索引名。

解决这个问题的关键(对我来说)是确保 $table-> drop Foreign ()命令传递的是正确的关系名,而不一定是列名。你做 没有想要传递列名,因为将是更直观的 IMHO。

对我起作用的是:

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

所以我传递给 drop Foreign ()的字符串的格式是:

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

如果你能使用 Sequel Pro 或者 Navicat 这样的工具,能够将它们可视化将会非常有帮助。

我突然想到,我不知道把 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就可以了。

我的表中有多个外键,然后我必须通过在 down 方法中将列名作为数组的索引一个一个地移除外键约束:

public function up()
{
Schema::table('offices', function (Blueprint $table) {
$table->unsignedInteger('country_id')->nullable();
$table->foreign('country_id')
->references('id')
->on('countries')
->onDelete('cascade');


$table->unsignedInteger('stateprovince_id')->nullable();
$table->foreign('stateprovince_id')
->references('id')
->on('stateprovince')
->onDelete('cascade');
$table->unsignedInteger('city_id')->nullable();
$table->foreign('city_id')
->references('id')
->on('cities')
->onDelete('cascade');
});
}


/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('offices', function (Blueprint $table) {
$table->dropForeign(['country_id']);
$table->dropForeign(['stateprovince_id']);
$table->dropForeign(['city_id']);
$table->dropColumn(['country_id','stateprovince_id','city_id']);
});
}

使用下面的语句不起作用

$table->dropForeign(['country_id','stateprovince_id','city_id']);

因为 dropForeign 不认为它们是我们要删除的独立列。所以我们必须一个一个地干掉他们。

您可以先禁用关系 ID

Schema::disableForeignKeyConstraints();

在幼虫8上使用 降低限制外来物种 (https://github.com/laravel/framework/pull/34806)

<?php


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;


class AddAddressFieldsInEventTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
        

Schema::table('events', function (Blueprint $table) {
$table->bigInteger('address_id')->nullable();


$table->foreign('address_id')
->references('id')
->on('addresses')
->onDelete('cascade');
});
}


/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('events', function (Blueprint $table) {
$table->dropConstrainedForeignId('address_id');
$table->dropColumn('address_id');
});
}
}