web-dev-qa-db-ja.com

外部キー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');
    });
}

この移行を実行すると、次のエラーが表示されます。

[Illuminate\Database\QueryException]
SQLSTATE [HY000]:一般エラー:1025「./dev_iwms_reboot/despatch_discrepancies」から「./dev_iwms_reboot/#sql2-67c-17c464」への名前変更時のエラー(errno:152)(SQL:alter table despatch_discrepancies drop外部キーpick_detail_id)

[PDOException]
SQLSTATE [HY000]:一般エラー:1025 25

php artisan migrate:rollbackコマンドを実行してこの移行を逆にしようとすると、Rolled backメッセージが表示されますが、実際にはデータベースで何もしていません。

何が間違っているのでしょうか?外部キー参照を持つ列をどのようにドロップしますか?

65
Latheesan

それが判明;このような外部キーを作成すると:

$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
68
Latheesan

これを使用できます:

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

DropForeignソースでピークを取る場合、列名を配列として渡すと、外部キーインデックス名が作成されます。

121
Alex Pineda

テーブルに複数の外部キーがあり、downメソッドで配列のインデックスとして列名を渡すことにより、外部キー制約を1つずつ削除する必要がありました。

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は、削除したい個別の列を考慮しないためです。そのため、それらを1つずつドロップする必要があります。

16
Afraz Ahmad

列名で配列を渡す

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

これを解決するためのキー(私にとって)は、$ table-> dropForeign()コマンドに列名ではなく正しい関係名が渡されるようにすることでした。 notより直感的なIMHOのように、列名を渡したい場合。

私のために働いたのは:

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

だから、私のために働いたdropForeign()に渡した文字列は次の形式でした:

[ローカルテーブル] _[外部キーフィールド] _ foreign

Sequel ProやNavicatのようなツールにアクセスできる場合、それらを視覚化できると非常に役立ちます。

9
DirtyBirdNJ

私が思いついたのは、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がトリックを行います。

4
Gus