J'ai créé une table en utilisant la migration comme ceci:
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');
}
Je dois changer cette table et supprimer la référence de clé étrangère & column pick_detail_id
Et ajouter une nouvelle colonne varchar appelée sku
après la colonne pick_id
.
J'ai donc créé une autre migration, qui ressemble à ceci:
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');
});
}
Lorsque j'exécute cette migration, j'obtiens le message d'erreur suivant:
[Illuminate\Database\QueryException]
SQLSTATE [HY000]: Erreur générale: 1025 Erreur lors du changement de nom de './dev_iwms_reboot/despatch_discrepancies' en './dev_iwms_reboot/#sql2-67c-17c464' (errno: 152) (SQL: alter tabledespatch_discrepancies
Déposer la clé étrangère pick_detail_id)[PDOException]
SQLSTATE [HY000]: Erreur générale: 1025 Erreur lors du changement de nom de './dev_iwms_reboot/despatch_discrepancies' en './dev_iwms_reboot/#sql2-67c-17c464' (errno: 152)
Lorsque j'essaie d'inverser cette migration en exécutant la commande php artisan migrate:rollback
, Je reçois un message Rolled back
, Mais il ne fait rien dans la base de données.
Une idée de ce qui pourrait être faux? Comment peut-on supprimer une colonne qui a une référence de clé étrangère?
Il s'avère; quand vous créez une clé étrangère comme ceci:
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
Laravel nomme de manière unique la référence de clé étrangère comme suit:
<table_name>_<foreign_table_name>_<column_name>_foreign
despatch_discrepancies_pick_detail_id_foreign (in my case)
Par conséquent, lorsque vous souhaitez supprimer une colonne avec une référence de clé étrangère, vous devez procéder comme suit:
$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign');
$table->dropColumn('pick_detail_id');
Laravel 4.2+ introduit une nouvelle convention de nommage:
<table_name>_<column_name>_foreign
Vous pouvez utiliser ceci:
$table->dropForeign(['pick_detail_id']);
$table->dropColumn('pick_detail_id');
Si vous prenez un pic chez dropForeign source, le nom de l'index de la clé étrangère sera créé si vous transmettez le nom de la colonne en tant que tableau.
J'avais plusieurs clés étrangères dans ma table, puis je devais supprimer les contraintes de clé étrangère une par une en passant le nom de la colonne à l'index du tableau dans la méthode 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']);
});
}
L'utilisation de la déclaration ci-dessous ne fonctionne pas
$table->dropForeign(['country_id','stateprovince_id','city_id']);
Parce que dropForeign ne les considère pas comme des colonnes distinctes que nous voulons supprimer. Nous devons donc les supprimer un à un.
Passer un tableau avec col name
$table->dropForeign(['user_id']);
La solution (pour moi) pour résoudre ce problème était de s'assurer que la commande $ table-> dropForeign () était transmise au bon nom de relation, pas nécessairement au nom de colonne. Vous ne voulez pas transmettre le nom de la colonne, ce qui serait beaucoup plus intuitif à mon humble avis.
Ce qui a fonctionné pour moi a été:
$table->dropForeign('local_table_foreign_id_foreign');
$table->column('foreign_id');
Ainsi, la chaîne que j'ai transmise à dropForeign () et qui a fonctionné pour moi était au format:
[table locale] _ [champ de clé étrangère] _ étranger
Si vous avez accès à un outil comme Sequel Pro ou Navicat, il vous sera très utile de pouvoir les visualiser.
Je me suis dit que je ne savais pas où placer le bloc Schema::table
.
Plus tard, j'ai découvert que la clé est sur l'erreur 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`)
Donc, le bloc Schema::table
Doit être inséré dans la fonction down()
de la migration lu_benefits_categories
Et avant la ligne 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');
}
Après cela, le php artisan migrate:refresh
Ou php artisan migrate:reset
Fera l'affaire.