J'ai créé une table en utilisant la migration comme celle-ci:
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 et la colonne de clé étrangère pick_detail_id
et ajouter une nouvelle colonne varchar appelée sku
après la pick_id
colonne.
Donc, j'ai 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 l'erreur suivante:
[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' (numéro d'erreur: 152) (SQL: modifier la 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» (numéro d'erreur: 152)
Lorsque j'essaye d'inverser cette migration en exécutant la php artisan migrate:rollback
commande, j'obtiens un Rolled back
message, mais cela ne fait rien dans la base de données.
Une idée de ce qui ne va pas? Comment supprimer une colonne qui a une référence de clé étrangère?
la source
Il s'avère; lorsque vous créez une clé étrangère comme celle-ci:
$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 le faire comme suit:
$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign'); $table->dropColumn('pick_detail_id');
Mise à jour:
Laravel 4.2+ introduit une nouvelle convention de dénomination:
la source
<table_name>_<column_name>_foreign
convention semble toujours fonctionner pour 5.1$table->dropIndex('column_name')
.J'avais plusieurs clés étrangères dans ma table, puis j'ai dû supprimer les contraintes de clé étrangère une par une en passant le nom de la colonne comme 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 l'instruction ci-dessous ne fonctionne pas
$table->dropForeign(['country_id','stateprovince_id','city_id']);
Parce que dropForeign ne les considère pas comme des colonnes séparées que nous voulons supprimer. Nous devons donc les supprimer un par un.
la source
$table->dropIndex('column_name')
.La clé (pour moi) pour résoudre ce problème était de s'assurer que la commande $ table-> dropForeign () recevait le bon nom de relation, pas nécessairement le nom de la colonne. Vous ne pas voulez passer le nom de colonne, comme ce serait à mon humble avis beaucoup plus intuitive.
Ce qui a fonctionné pour moi était:
$table->dropForeign('local_table_foreign_id_foreign'); $table->column('foreign_id');
Donc, la chaîne que j'ai passée à dropForeign () qui fonctionnait pour moi était au format:
[table locale] _ [champ de clé étrangère] _foreign
Si vous avez accès à un outil comme Sequel Pro ou Navicat, il sera très utile de pouvoir les visualiser.
la source
Quelque chose qui m'est venu à l'esprit était que je ne savais pas où placer le
Schema::table
bloc.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`)
Le
Schema::table
bloc doit donc aller dans ladown()
fonction de lalu_benefits_categories
migration et avant laSchema::dropIfExists
ligne: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
ouphp artisan migrate:reset
fera l'affaire.la source