외래 키가있는 열 삭제 Laravel 오류 : 일반 오류 : 1025 이름 바꾸기 오류


94

다음과 같이 마이그레이션을 사용하여 테이블을 만들었습니다.

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뒤에 호출되는 새 varchar 열을 추가해야합니다 pick_id.

그래서 다음과 같은 또 다른 마이그레이션을 만들었습니다.

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'(오류 번호 : 152)로 바꿀 때 1025 오류 발생 (SQL : alter table despatch_discrepancies외래 키 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메시지 가 표시되지만 실제로 데이터베이스에서 아무 작업도 수행하지 않습니다.

무엇이 잘못되었는지 아십니까? 외래 키 참조가있는 열을 어떻게 삭제합니까?

답변:


167

이것을 사용할 수 있습니다 :

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

dropForeign 소스에서 정점을 찍으면 열 이름을 배열로 전달하면 외래 키 인덱스 이름이 빌드됩니다.


2
허용되는 대답도 작동합니다. 올바른 인덱스 이름 규칙을 사용해야합니다. 그러나 이것이 그 대답의 문제이기도합니다. 인덱스의 명명 체계를 기억해야하지만이 솔루션은 자동으로 수행합니다! 나는 항상 다른 방법을 사용했고 그것이 얼마나 비현실적인지 항상 불평했다. 이제 즉시이 솔루션으로 전환합니다. 대단히 감사합니다!
Marco Pallante 2015

6
멋진 속임수. 나는 멍청이처럼 먼 길을 해왔다. Laravel은 실제로 문서에 대한 일부 도움말을 사용할 수 있습니다. 나는 ... 도전을 걸릴 수 있습니다
simonhamp

1
Laravel 5.0에서 나를 위해 일했습니다. 감사합니다, Alex!
SilithCrowe

1
Laravel 5.2에서 매력처럼 작동했습니다.
ronin1184

3
이것은 깔끔한 트릭입니다. 외래 키 명명 규칙을 기억하는 것보다 훨씬 친숙합니다 (향후 변경 될 수 있음). @ ronin1184가 말했듯이, Laravel 5.2에서 완벽하게 작동합니다
Robin van

81

그것은 밝혀; 다음과 같은 외래 키를 만들 때 :

$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

4
Laravel 4.2에서는 작동하지 않습니다. <foreign_table_name>은 키 이름의 일부가 아닙니다. <table_name> _ <column_name> _foreign에서만 작동합니다.
rich remer 2015

나는 그것을 laravel 4.2에서 사용했지만 여전히 작동합니다.
Latheesan 2015-06-12

2
<table_name>_<column_name>_foreign규칙은 여전히 5.1 작동하는 것 같다
야야 Uddin에게

관계에 대한 제약 조건을 삭제 한 후에는 열도 삭제해야합니다. dropForeign이 열을 삭제할 것이라고 쉽게 가정 할 수 있기 때문에 문서에도 포함되어야한다고 생각합니다. 공유해 주셔서 감사합니다. laravel.com/docs/5.0/schema#dropping-columns
Picrasma

궁금한 사람이 있다면 MySQL이 외래 키에 대해 자동으로 생성하는 인덱스는 열이있을 때 삭제됩니다. 을 사용하여 수동으로 삭제할 필요가 없습니다 $table->dropIndex('column_name').
Aleksandar

24

내 테이블에 여러 외래 키가 있었고 열 이름을 배열의 인덱스로 전달하여 외래 키 제약 조건을 하나씩 제거해야했습니다.

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은 제거하려는 별도의 열을 고려하지 않기 때문입니다. 그래서 우리는 그것들을 하나씩 떨어 뜨려야합니다.


친구에게 감사합니다. 배열에 열 이름을 추가하면 저에게 효과적입니다.
Pierre

궁금한 사람이 있다면 MySQL이 외래 키에 대해 자동으로 생성하는 인덱스는 열이있을 때 삭제됩니다. 을 사용하여 수동으로 삭제할 필요가 없습니다 $table->dropIndex('column_name').
Aleksandar

9

이 문제를 해결하기위한 핵심은 $ table-> dropForeign () 명령이 반드시 열 이름이 아니라 올바른 관계 이름을 전달하고 있는지 확인하는 것이 었습니다. 당신은 할 수 없습니다 만큼 직관적 이럴 것, 열 이름을 전달하려는.

나를 위해 일한 것은 다음과 같습니다.

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

그래서 나를 위해 일한 dropForeign ()에 전달한 문자열은 다음과 같은 형식이었습니다.

[로컬 테이블] _ [외래 키 필드] _foreign

Sequel Pro 또는 Navicat과 같은 도구에 액세스 할 수있는 경우이를 시각화 할 수 있으면 매우 유용합니다.


이것은 잘 작동하지만 @Alex가 제안한 것처럼 테이블을 괄호로 묶는 것보다 덜 직관적이라는 것을 알았습니다.
Mark Karavan

5

나에게 일어난 일은 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블록 down()lu_benefits_categories마이그레이션 기능에서 다음 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트릭을 할 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.