Odpravite napako »a foreign key constraint fails« pri uvozu SQL izvoza

Vaš uvoz se ustavi na pol poti z Cannot add or update a child row: a foreign key constraint fails. Podatki so v redu — napačen je vrstni red INSERT stavkov. Tu je razlog, zakaj se to zgodi, in trije načini, kako to odpraviti.

Izvozite bazo podatkov, jo poskusite naložiti v svežo instanco, MySQL pa vrže:

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`))

Ali pa na 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".

Zakaj se to zgodi

Tuji ključ pravi »vsak orders.user_id mora kazati na obstoječi users.id.« Kadar izvoz vstavi orders pred users, referencirana nadrejena vrstica še ne obstaja in baza podatkov vrstico zavrne.

Večina orodij za izvoz zapiše tabele po abecedi ali v vrstnem redu ustvarjanja — ne v vrstnem redu odvisnosti tujih ključev. Zato orders (podrejena) pogosto pristane pred users (nadrejena) in uvoz se pokvari.

Rešitev 1: Prerazporedite INSERT stavke po odvisnostih (pravilna rešitev)

Čista rešitev je, da vsako nadrejeno tabelo vstavite pred njenimi podrejenimi. To pomeni, da tuje ključe razrešite v graf odvisnosti in tabele naložite v topološkem vrstnem redu: users → orders → order_items.

Ročno početje tega v datoteki velikosti več gigabajtov je mučno — izslediti morate vsak FOREIGN KEY po vseh CREATE TABLE in ALTER TABLE stavkih ter v pravilnem zaporedju izrezovati in lepiti ogromne INSERT bloke.

Rešitev 2: Onemogočite preverjanje tujih ključev med uvozom

Pri popolnem in že usklajenem izvozu lahko med nalaganjem varno preskočite preverjanje. Na MySQL datoteko ovijete:

-- MySQL
SET FOREIGN_KEY_CHECKS = 0;
-- ... vsi vaši INSERT stavki ...
SET FOREIGN_KEY_CHECKS = 1;

Na PostgreSQL omejitve odložite znotraj transakcije:

-- PostgreSQL
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
-- ... vsi vaši INSERT stavki ...
COMMIT;

Preverjanje nato znova omogočite, da ostanejo prihodnji zapisi preverjeni. To deluje, a le prikrije težavo z vrstnim redom — če je izvoz delen, lahko še vedno pristanete z osirotelimi vrsticami.

Rešitev 3: Naredite oboje samodejno z DumpCleaner

DumpCleaner prebere izvoz, iz CREATE TABLE in ALTER TABLE izlušči vsak tuji ključ, zgradi graf odvisnosti in izvozi čisto datoteko, ki se preprosto uvozi:

  1. Povlecite svoj .sql izvoz v DumpCleaner (MySQL, MariaDB, PostgreSQL, SQLite ali MS SQL).
  2. Izberite Vrstni red INSERT → Po odvisnostih (upošteva tuje ključe). Nadrejene tabele so samodejno postavljene pred podrejene s topološkim urejanjem.
  3. Po želji obkljukajte Onemogoči preverjanje tujih ključev — izhod se ovije s pravilnim stavkom za vašo bazo podatkov.
  4. Izvozite. Uvozite novo datoteko — napake omejitve ni več.

Zazna celo krožne tuje ključe in vas opozori, namesto da bi ustvaril nemogoč vrstni red.

Konec ročnega operiranja z INSERT stavki

DumpCleaner prerazporedi vstavljanja po odvisnostih tujih ključev na datotekah katere koli velikosti — pretočno, s konstantno porabo pomnilnika. Domača aplikacija za macOS in iPadOS, enkraten nakup.

Prenesi v trgovini App Store

Pogosta vprašanja

Zakaj se pri uvozu pojavi »a foreign key constraint fails«?

Podrejena vrstica se sklicuje na nadrejeno vrstico, ki še ni bila vstavljena, ker izvoz razvrsti INSERT stavke po abecedi ali po času ustvarjanja namesto po odvisnosti tujih ključev.

Ali je varno onemogočiti preverjanje tujih ključev med uvozom?

Da, pri popolnem in usklajenem izvozu. Preskočite le preverjanje podatkov, ki so bili v izvorni bazi že veljavni. Preverjanje nato znova omogočite.

Kako prerazporedim INSERT stavke, ne da bi ročno urejal datoteko?

DumpCleaner zazna tuje ključe, zgradi graf odvisnosti in izvozi INSERT stavke v topološkem vrstnem redu — tako se nadrejene tabele vedno naložijo pred podrejenimi.

Ali to deluje tudi za PostgreSQL?

Da. DumpCleaner podpira izhod pg_dump in lahko izda SET CONSTRAINTS ALL DEFERRED ter vstavljanja, urejena po odvisnostih.

Uvozite izvoze brez glavobolov s tujimi ključi

Povlecite, prerazporedite po odvisnostih, izvozite. DumpCleaner poskrbi za tuje ključe, tako da vaš uvoz preprosto deluje.

Prenesi v trgovini App Store