Corregeix «a foreign key constraint fails» en importar un abocament SQL

La importació s'atura a mig camí amb Cannot add or update a child row: a foreign key constraint fails. Les dades estan bé: l'ordre de les sentències INSERT és el que està malament. Aquí tens per què passa i tres maneres de solucionar-ho.

Exportes una base de dades, intentes carregar-la en una instància nova i MySQL llança:

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`app`.`orders`, CONSTRAINT `orders_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))

O bé, a PostgreSQL:

ERROR: insert or update on table "orders" violates foreign key constraint "orders_user_id_fkey"
DETAIL: Key (user_id)=(42) is not present in table "users".

Per què passa això

Una clau forana diu «cada orders.user_id ha d'apuntar a un users.id existent». Quan l'abocament insereix orders abans de users, la fila pare referenciada encara no existeix, i la base de dades rebutja la fila.

La majoria d'eines d'abocament escriuen les taules alfabèticament o en ordre de creació, no en ordre de dependència de claus foranes. Així doncs, orders (filla) sovint acaba abans que users (pare), i la importació es trenca.

Solució 1: Reordena els INSERT per dependència (la solució correcta)

La solució neta és inserir cada taula pare abans que les seves filles. Això vol dir resoldre les claus foranes en un graf de dependències i carregar les taules en ordre topològic: users → orders → order_items.

Fer-ho a mà en un fitxer de diversos gigabytes és penós: has de rastrejar cada FOREIGN KEY a través de les sentències CREATE TABLE i ALTER TABLE i retallar/enganxar blocs INSERT enormes en la seqüència correcta.

Solució 2: Desactiva les comprovacions de clau forana durant la importació

Per a un abocament complet i ja consistent pots ometre amb seguretat la validació durant la càrrega. A MySQL, embolcalla el fitxer:

-- MySQL
SET FOREIGN_KEY_CHECKS = 0;
-- ... totes les teves sentències INSERT ...
SET FOREIGN_KEY_CHECKS = 1;

A PostgreSQL, ajorna les restriccions dins d'una transacció:

-- PostgreSQL
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
-- ... totes les teves sentències INSERT ...
COMMIT;

Torna a activar les comprovacions després perquè les escriptures futures continuïn validades. Això funciona, però només emmascara el problema d'ordenació: si l'abocament és parcial, encara pots acabar amb files òrfenes.

Solució 3: Fes les dues coses automàticament amb DumpCleaner

DumpCleaner llegeix l'abocament, extreu cada clau forana de CREATE TABLE i ALTER TABLE, construeix el graf de dependències i exporta un fitxer net que simplement s'importa:

  1. Arrossega el teu abocament .sql a DumpCleaner (MySQL, MariaDB, PostgreSQL, SQLite o MS SQL).
  2. Tria Ordre dels INSERT → Per dependències (conscient de les FK). Els pares es col·loquen abans que les filles automàticament mitjançant l'ordenació topològica.
  3. Opcionalment, marca Desactiva les comprovacions de clau forana: embolcalla la sortida amb la sentència correcta per a la teva base de dades.
  4. Exporta. Importa el fitxer nou: l'error de restricció ha desaparegut.

Fins i tot detecta claus foranes circulars i t'avisa en lloc de produir un ordre impossible.

S'ha acabat la cirurgia manual dels INSERT

DumpCleaner reordena els inserts per dependència de clau forana en fitxers de qualsevol mida: en flux, amb memòria constant. Aplicació nativa de macOS i iPadOS, compra única.

Baixa-la a l'App Store

Preguntes freqüents

Per què passa «a foreign key constraint fails» en importar?

Una fila filla referencia una fila pare que encara no s'ha inserit, perquè l'abocament ordena els INSERT alfabèticament o per data de creació en lloc de per dependència de clau forana.

És segur desactivar les comprovacions de clau forana durant la importació?

Sí, per a un abocament complet i consistent. Només omets la validació de dades que ja eren vàlides a la base de dades d'origen. Torna a activar les comprovacions després.

Com reordeno els INSERT sense editar el fitxer a mà?

DumpCleaner detecta les claus foranes, construeix un graf de dependències i exporta els INSERT en ordre topològic, de manera que els pares sempre es carreguen abans que les filles.

Això també funciona amb PostgreSQL?

Sí. DumpCleaner admet la sortida de pg_dump i pot emetre SET CONSTRAINTS ALL DEFERRED així com inserts ordenats per dependència.

Importa abocaments sense el maldecap de les FK

Arrossega, reordena per dependències, exporta. DumpCleaner s'encarrega de les claus foranes perquè la teva importació simplement funcioni.

Baixa-la a l'App Store