web-dev-qa-db-fra.com

Utilisation de migrations pour supprimer une table avec une clé étrangère

J'essaie de faire reculer mes migrations.

Mon fichier de migration utilise des clés étrangères comme

$table->foreign('user_one')->references('id')->on('users');
$table->foreign('user_two')->references('id')->on('users');

Ma fonction down () est comme si

public function down()
{
    Schema::drop('pm_convo');
    Schema::drop('pm_convo_replys');
}

Quand je lance ma commande migrate

php artisan migrate:refresh --seed --env=local

Je reçois l'erreur suivante

SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table `pm_convo`) 

Je ne sais pas exactement quoi faire pour résoudre ce problème.

Modifier:

J'ai essayé: $table->dropForeign('pm_convo_user_one_foreign');

Mais im obtenir des erreurs avec cela aussi

41
BigJobbies

pm_convo_replys a une clé étrangère qui référence pm_convo. Par conséquent, vous ne pouvez pas supprimer pm_convo en premier sans violer une contrainte de clé étrangère dans pm_convo_replys.

Pour supprimer les deux, vous devez supprimer d'abord pm_convo_replys.

public function down()
{
    Schema::drop('pm_convo_replys');
    Schema::drop('pm_convo');
}
56
Nils Werner

Je pense que c'est une meilleure façon de le faire:

public function down()
{
    DB::statement('SET FOREIGN_KEY_CHECKS = 0');
    Schema::dropIfExists('tableName');
    DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
67
Eric Chan

J'ai aussi fait face à ce genre de problèmes. L'ordre des fichiers de migration est le problème principal ici. Le meilleur moyen est de créer les fichiers de migration un par un. Les entités principales doivent être créées en premier. La migration doit être actualisée à chaque création de fichier de migration. (avec php artisan migrate:refresh

Selon @abkrim et @Eric

public function down()
{
    Schema::disableForeignKeyConstraints();
    Schema::drop('tableName');
    Schema::enableForeignKeyConstraints();
}
19
Dinuka Thilanga

Je pense que c'est l'approche la plus correcte:

public function down()
{
    Schema::table('[table]', function (Blueprint $table) {
        $table->dropForeign('[table]_[column]_foreign');
        $table->dropColumn('[column]');
    });
}
7
eithed

préfère le faire de cette façon

    Schema::dropIfExists('tableNameChild');
    Schema::drop('tableNameParents');
3
ken

Important, ceci concerne Laravel 5.4.

Selon les docs

Pour supprimer une clé étrangère, vous pouvez utiliser la méthode dropForeign. Les contraintes de clé étrangère utilisent la même convention d'appellation que les index. Nous allons donc concaténer le nom de la table et les colonnes de la contrainte, puis suffixer le nom "_foreign"

$table->dropForeign('posts_user_id_foreign');

Vous pouvez également passer une valeur de tableau qui utilisera automatiquement le nom de la contrainte conventionnelle lors de la suppression:

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

Personnellement, je préfère le second en raison de la simplicité

0
Iván Sánchez

Vous pouvez le faire très facilement si vous avez ajouté cascade au foeign key lors de la création de la table. Si vous l'avez fait, vous pouvez très facilement supprimer la table sans quelque chose comme ceci pour PostgreSQL.

DB::statement("drop table tableName if exists cascade");

Tout ce que vous avez à faire est de mettre l'instruction pour la table SQL au format brut.

0
Koushik Das