删除具有外键的列Laravel错误:一般错误:1025重新命名时发生错误

wmvff8tz  于 2022-12-14  发布在  其他
关注(0)|答案(8)|浏览(141)

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

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

运行此迁移时,出现以下错误:
[说明\数据库\查询异常]
SQL状态[HY 000]:一般错误:1025将.“/dev_iwms_reboot/调度差异”重命名为.“/dev_iwms_reboot/#sql2- 67 c-17 c464”时出错(错误号:152)(SQL:更改表despatch_discrepancies删除外键pick_detail_id)
[PDO例外]
SQL状态[HY 000]:一般错误:1025将.“/dev_iwms_reboot/调度差异”重命名为.“/dev_iwms_reboot/#sql2- 67 c-17 c464”时出错(错误号:152)
当我尝试通过运行php artisan migrate:rollback命令来反转此迁移时,我收到一条Rolled back消息,但它实际上没有在数据库中执行任何操作。
你知道哪里出了问题吗?如何删除一个有外键引用的列?

hof1towb

hof1towb1#

您可以使用此选项:

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

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

nsc4cvqm

nsc4cvqm2#

事实证明;当你创建一个如下的外键时:

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

这将删除该列及其外键

2j4z5cfb

2j4z5cfb3#

我的表中有多个外键,然后我必须通过在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']);
    });
}

使用below语句无效

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

因为dropForeign不会将它们视为我们要删除的独立列。所以我们必须逐个删除它们。

watbbzwu

watbbzwu4#

解决这个问题的关键(对我来说)是确保$table-〉dropForeign()命令传递的是正确的关系名,而不一定是列名。您希望传递列名,这样会更直观。
对我有用的是:

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

因此,我传递给dropForeign()的字符串的格式为:

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

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

9nvpjoqh

9nvpjoqh5#

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

44u64gxh

44u64gxh6#

在laravel 8上使用删除受约束的外部IDhttps://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');
        });
    }
}
31moq8wy

31moq8wy7#

您可以先禁用关系标识

Schema::disableForeignKeyConstraints();
lnvxswe2

lnvxswe28#

在Larave中〉8.x

添加

$table->foreignId('pick_id')->constrained('picks')->cascadeOnUpdate()
->cascadeOnDelete();

跌落

$table->dropConstrainedForeignId('pick_id');

相关问题