Oprava chyby „a foreign key constraint fails" při importu SQL dumpu

Import se zastaví v polovině s hláškou Cannot add or update a child row: a foreign key constraint fails. S daty je vše v pořádku — chybné je pořadí příkazů INSERT. Vysvětlíme, proč k tomu dochází, a ukážeme tři způsoby, jak to opravit.

Exportujete databázi, pokusíte se ji načíst do čisté instance a MySQL vyhodí:

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

Nebo v 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".

Proč k tomu dochází

Cizí klíč říká, že „každý orders.user_id musí ukazovat na existující users.id“. Když dump vloží tabulku orders před tabulkou users, odkazovaný nadřazený řádek ještě neexistuje a databáze řádek odmítne.

Většina nástrojů pro export zapisuje tabulky abecedně nebo v pořadí vytvoření — nikoli podle závislostí cizích klíčů. Proto se orders (podřízená) často ocitne před users (nadřazená) a import selže.

Řešení 1: Přeuspořádat INSERTy podle závislostí (správná oprava)

Čisté řešení je vložit každou nadřazenou tabulku před její podřízené. To znamená převést cizí klíče na graf závislostí a načítat tabulky v topologickém pořadí: users → orders → order_items.

Dělat to ručně v souboru o velikosti mnoha gigabajtů je utrpení — musíte vysledovat každý FOREIGN KEY napříč příkazy CREATE TABLE a ALTER TABLE a vyjímat a vkládat obrovské bloky INSERT ve správném pořadí.

Řešení 2: Vypnout kontrolu cizích klíčů během importu

U kompletního a již konzistentního dumpu můžete během načítání validaci bezpečně přeskočit. V MySQL soubor obalte:

-- MySQL
SET FOREIGN_KEY_CHECKS = 0;
-- ... všechny vaše příkazy INSERT ...
SET FOREIGN_KEY_CHECKS = 1;

V PostgreSQL odložte omezení uvnitř transakce:

-- PostgreSQL
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
-- ... všechny vaše příkazy INSERT ...
COMMIT;

Poté kontroly znovu zapněte, aby zůstaly budoucí zápisy validovány. Funguje to, ale pouze zamaskuje problém s pořadím — pokud je dump částečný, můžete stále skončit s osiřelými řádky.

Řešení 3: Obojí automaticky s DumpCleaner

DumpCleaner načte dump, extrahuje každý cizí klíč z CREATE TABLE a ALTER TABLE, sestaví graf závislostí a vyexportuje čistý soubor, který se prostě naimportuje:

  1. Přetáhněte svůj .sql dump do DumpCleaner (MySQL, MariaDB, PostgreSQL, SQLite nebo MS SQL).
  2. Zvolte Pořadí INSERTů → Podle závislostí (podle cizích klíčů). Nadřazené tabulky se automaticky umístí před podřízené pomocí topologického řazení.
  3. Volitelně zaškrtněte Vypnout kontrolu cizích klíčů — výstup se obalí správným příkazem pro vaši databázi.
  4. Exportujte. Naimportujte nový soubor — chyba omezení je pryč.

Dokonce detekuje cyklické cizí klíče a upozorní vás, místo aby vytvořil nemožné pořadí.

Konec ručnímu chirurgickému zásahu do INSERTů

DumpCleaner přeuspořádá vkládání podle závislostí cizích klíčů u souborů libovolné velikosti — streamovaně, s konstantní pamětí. Nativní aplikace pro macOS a iPadOS, jednorázový nákup.

Stáhnout z App Store

Časté dotazy

Proč dochází při importu k „a foreign key constraint fails"?

Podřízený řádek odkazuje na nadřazený řádek, který ještě nebyl vložen, protože dump řadí INSERTy abecedně nebo podle času vytvoření místo podle závislostí cizích klíčů.

Je bezpečné vypnout kontrolu cizích klíčů během importu?

Ano, u kompletního a konzistentního dumpu. Pouze přeskakujete validaci dat, která už byla ve zdrojové databázi platná. Poté kontroly znovu zapněte.

Jak přeuspořádat INSERTy bez ručního editování souboru?

DumpCleaner detekuje cizí klíče, sestaví graf závislostí a exportuje INSERTy v topologickém pořadí — takže nadřazené tabulky se vždy načtou před podřízenými.

Funguje to i pro PostgreSQL?

Ano. DumpCleaner podporuje výstup pg_dump a umí vygenerovat SET CONSTRAINTS ALL DEFERRED i vkládání seřazené podle závislostí.

Import dumpů bez starostí s cizími klíči

Přetáhnout, přeuspořádat podle závislostí, exportovat. DumpCleaner se postará o cizí klíče, takže váš import prostě funguje.

Stáhnout z App Store