Удаление столбца с внешним ключом Ошибка 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 и добавьте новый столбец varchar под названием sku после 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');
});
}

Когда я запускаю эту миграцию, я получаю следующую ошибку:

[Осветите \ Database \ QueryException] SQLSTATE [HY000]: общая ошибка: 1025 Ошибка при переименовании
«./dev_iwms_reboot/despatch_discrepancies» для
‘./dev_iwms_reboot/#sql2-67c-17c464’ (номер ошибки: 152) (SQL: изменить таблицу
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 сообщение, но на самом деле он ничего не делает в базе данных.

Есть идеи, что может быть не так? Как удалить столбец со ссылкой на внешний ключ?

54

Решение

Вы можете использовать это:

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

Если вы возьмете пик в источнике dropForeign, он создаст для вас имя индекса внешнего ключа, если вы передадите имя столбца в виде массива.

103

Другие решения

Оказывается; когда вы создаете внешний ключ, как это:

$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
62

Передать массив с именем col

$table->dropForeign(['user_id']);
9

У меня было несколько внешних ключей в моей таблице, а затем я должен был удалить ограничения внешнего ключа одно за другим, передавая имя столбца как индекс массива в методе 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 не считает их отдельными столбцами, которые мы хотим удалить. Поэтому мы должны отбросить их один за другим.

9

Ключ (для меня) к решению этой проблемы состоял в том, чтобы убедиться, что команде $ table-> dropForeign () было передано правильное имя отношения, а не имя столбца. Ты сделаешь не хочу передать имя столбца, так как было бы гораздо более интуитивным ИМХО.

Что сработало для меня:

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

Итак, строка, которую я передал dropForeign (), которая работала для меня, была в формате:

[локальная таблица]_[поле внешнего ключа]_foreign

Если у вас есть доступ к таким инструментам, как Sequel Pro или Navicat, возможность их визуализации будет очень полезна.

8

Что-то, что пришло мне в голову, было то, что я не знал, где поставить 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 сделает свое дело.

4