Utworzyłem tabelę przy użyciu migracji w następujący sposób:
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');
}
Muszę zmienić tę tabelę i usunąć odwołanie do klucza obcego i kolumnę pick_detail_id
oraz dodać nową kolumnę varchar o nazwie sku
po pick_id
kolumnie.
Utworzyłem więc kolejną migrację, która wygląda następująco:
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');
});
}
Kiedy uruchamiam tę migrację, pojawia się następujący błąd:
[Illuminate \ Database \ QueryException]
SQLSTATE [HY000]: Błąd ogólny: 1025 Błąd podczas zmiany nazwy „./dev_iwms_reboot/despatch_discrepancies” na „./dev_iwms_reboot/#sql2-67c-17c464” (errno: 152) (SQL: alter tabledespatch_discrepancies
upuść klucz obcy pick_detail_id)[PDOException]
SQLSTATE [HY000]: Błąd ogólny: 1025 Błąd podczas zmiany nazwy „./dev_iwms_reboot/despatch_discrepancies” na „./dev_iwms_reboot/#sql2-67c-17c464” (errno: 152)
Kiedy próbuję cofnąć tę migrację, uruchamiając php artisan migrate:rollback
polecenie, otrzymuję Rolled back
komunikat, ale tak naprawdę nic nie robi w bazie danych.
Masz jakiś pomysł, co może być nie tak? Jak usunąć kolumnę zawierającą odniesienie do klucza obcego?
źródło
Wyszło na to, że; podczas tworzenia klucza obcego w ten sposób:
$table->integer('pick_detail_id')->unsigned(); $table->foreign('pick_detail_id')->references('id')->on('pick_details');
Laravel jednoznacznie nazywa odwołanie do klucza obcego w następujący sposób:
<table_name>_<foreign_table_name>_<column_name>_foreign despatch_discrepancies_pick_detail_id_foreign (in my case)
Dlatego jeśli chcesz usunąć kolumnę z odniesieniem do klucza obcego, musisz to zrobić w następujący sposób:
$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign'); $table->dropColumn('pick_detail_id');
Aktualizacja:
Laravel 4.2+ wprowadza nową konwencję nazewnictwa:
źródło
<table_name>_<column_name>_foreign
Konwencja wciąż wydaje się działać na 5,1$table->dropIndex('column_name')
.Miałem wiele kluczy obcych w mojej tabeli, a następnie musiałem usuwać ograniczenia klucza obcego jeden po drugim, przekazując nazwę kolumny jako indeks tablicy w metodzie w dół:
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']); }); }
Korzystanie z poniższej instrukcji nie działa
$table->dropForeign(['country_id','stateprovince_id','city_id']);
Ponieważ dropForeign nie uważa ich za oddzielne kolumny, które chcemy usunąć. Musimy więc porzucić je jeden po drugim.
źródło
$table->dropIndex('column_name')
.Kluczem (dla mnie) do rozwiązania tego problemu było upewnienie się, że do polecenia $ table-> dropForeign () została przekazana właściwa nazwa relacji, niekoniecznie nazwa kolumny. Zdajesz nie chce przekazać nazwę kolumny, jak byłoby znacznie bardziej intuicyjne IMHO.
U mnie zadziałało:
$table->dropForeign('local_table_foreign_id_foreign'); $table->column('foreign_id');
Tak więc ciąg, który przekazałem do dropForeign (), który działał dla mnie, był w formacie:
[tabela lokalna] _ [pole klucza obcego] _zewnętrzne
Jeśli masz dostęp do narzędzia takiego jak Sequel Pro lub Navicat, ich wizualizacja będzie bardzo pomocna.
źródło
Coś, co przyszło mi do głowy, to fakt, że nie wiedziałem, gdzie umieścić
Schema::table
blokadę.Później odkryłem, że klucz jest na błędzie 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`)
Więc
Schema::table
blok musi iść wdown()
funkcjilu_benefits_categories
migracji i przedSchema::dropIfExists
wierszem:public function down() { Schema::table('table', function (Blueprint $table) { $table->dropForeign('table_category_id_foreign'); $table->dropColumn('category_id'); }); Schema::dropIfExists('lu_benefits_categories'); }
Po tym,
php artisan migrate:refresh
lubphp artisan migrate:reset
załatwi sprawę.źródło