web-dev-qa-db-fra.com

Laravel migration - Violation de contrainte d'intégrité: 1452 Impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue

J'essaie d'exécuter une migration pour une table inventories que j'ai créée avec cette migration:

Schema::create('inventories', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('remote_id')->unsigned();
    $table->integer('local_id')->unsigned();
    $table->string('local_type');
    $table->string('url')->nullable()->unique();
    $table->timestamps();
});

J'essaie d'ajouter une exécution d'une migration où j'ajoute une clé étrangère à la table:

Schema::table('inventories', function (Blueprint $table) {
    $table->foreign('local_id')->references('id')->on('contents')->onDelete('cascade');
});

Mais, je reçois une erreur lorsque j'essaie d'exécuter la migration:

[Illuminate\Database\QueryException]

SQLSTATE [23000]: violation de contrainte d'intégrité: 1452 Impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue (middleton
.#sql-5d6_162a, CONTRAINTE inventories_local_id_foreign CLÉ ÉTRANGÈRE (local_id) RÉFÉRENCES contents (id) ON DELETE CASCADE) (SQL: modifier la table inventories ajouter une contrainte inventories_local_id_foreign clé étrangère (local_id) références contents (id) lors de la suppression d'une cascade)

[PDOException]

SQLSTATE [23000]: violation de contrainte d'intégrité: 1452 Impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue (middleton
.#sql-5d6_162a, CONTRAINTE inventories_local_id_foreign CLÉ ÉTRANGÈRE (local_id) RÉFÉRENCES contents (id) SUR SUPPRIMER LA CASCADE)

Qu'est-ce que je fais mal?

10
Leff

Vous avez probablement des enregistrements dans la table inventories avec local_id qui n'a pas de id correspondant dans la table contents, d'où l'erreur. Vous pouvez le résoudre de l'une des deux manières suivantes:

  • Exécutez la migration avec foreign_key_checks éteindre. Cela désactivera les contraintes de clé étrangère pour les lignes existantes (si c'est ce que vous voulez). C'est documenté ici
  • Insérez uniquement les enregistrements qui ont le champ id correspondant dans la table contents. Vous pouvez utiliser INSERT INTO.. WHERE EXISTS requête pour filtrer les enregistrements et insérer uniquement ces enregistrements.
9
Darshan Mehta

eu le même problème. corrigé en ajoutant nullable au champ

Schema::create('table_name', function (Blueprint $table) {
    ...
    $table->integer('some_id')->unsigned()->nullable();
    $table->foreign('some_id')->references('id')->on('other_table');
    ...
});

notez qu'après la migration, toutes les lignes existantes auront some_id = NULL

11
Roman Bobrik