Я создал таблицу с помощью миграции следующим образом:
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');
});
}
Когда я запускаю эту миграцию, я получаю следующую ошибку:
[Illuminate \ 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
сообщение, но на самом деле оно ничего не делает в базе данных.
Есть идеи, что может быть не так? Как удалить столбец со ссылкой на внешний ключ?
источник
Оказывается; когда вы создаете внешний ключ следующим образом:
$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
Конвенция по- прежнему кажется, работает на 5,1$table->dropIndex('column_name')
.У меня было несколько внешних ключей в моей таблице, и затем мне пришлось удалить ограничения внешнего ключа один за другим, передав имя столбца в качестве индекса массива в методе 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 не считает их отдельными столбцами, которые мы хотим удалить. Поэтому мы должны отбрасывать их по одному.
источник
$table->dropIndex('column_name')
.Ключом (для меня) к решению этой проблемы было убедиться, что команде $ table-> dropForeign () передается правильное имя отношения, не обязательно имя столбца. Вы не хотите передавать имя столбца, поскольку это было бы гораздо более интуитивно понятным ИМХО.
Для меня сработало:
$table->dropForeign('local_table_foreign_id_foreign'); $table->column('foreign_id');
Итак, строка, которую я передал в dropForeign (), которая сработала для меня, была в формате:
[локальная таблица] _ [поле внешнего ключа] _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
блок должен идти в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
сделает свое дело.источник