SQL 덤프를 가져올 때 발생하는 "a foreign key constraint fails" 오류 해결하기

가져오기가 도중에 Cannot add or update a child row: a foreign key constraint fails 메시지와 함께 멈춥니다. 데이터에는 문제가 없습니다. 잘못된 것은 INSERT 문의 순서입니다. 왜 이런 일이 발생하는지, 그리고 세 가지 해결 방법을 살펴봅니다.

데이터베이스를 내보낸 뒤 새 인스턴스에 로드하려고 하면 MySQL이 다음과 같은 오류를 냅니다:

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

또는 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".

왜 이런 일이 발생하나

외래 키는 "모든 orders.user_id는 존재하는 users.id를 가리켜야 한다"고 규정합니다. 덤프가 users 보다 먼저 orders를 삽입하면, 참조 대상인 부모 행이 아직 존재하지 않으므로 데이터베이스가 해당 행을 거부합니다.

대부분의 덤프 도구는 테이블을 알파벳순이나 생성 순서로 기록할 뿐, 외래 키 의존 관계 순서로 기록하지 않습니다. 그래서 orders(자식)가 users(부모)보다 먼저 놓이는 경우가 잦고, 가져오기가 실패합니다.

해결책 1: 의존 관계에 따라 INSERT 재정렬 (올바른 해결책)

깔끔한 해결책은 모든 부모 테이블을 자식보다 먼저 삽입하는 것입니다. 즉, 외래 키를 의존 관계 그래프로 해석하고 테이블을 위상 정렬 순서로 로드하는 것입니다: users → orders → order_items.

수 기가바이트짜리 파일에서 이 작업을 손으로 하는 것은 고통스럽습니다. 모든 FOREIGN KEYCREATE TABLEALTER TABLE 문에서 추적하고, 거대한 INSERT 블록을 올바른 순서로 잘라 붙여야 하기 때문입니다.

해결책 2: 가져오기 중 외래 키 검사 비활성화

이미 정합성이 보장된 완전한 덤프라면 로드하는 동안 검증을 안전하게 건너뛸 수 있습니다. MySQL에서는 파일을 다음과 같이 감쌉니다:

-- MySQL
SET FOREIGN_KEY_CHECKS = 0;
-- ... 모든 INSERT 문 ...
SET FOREIGN_KEY_CHECKS = 1;

PostgreSQL에서는 트랜잭션 안에서 제약 조건을 지연시킵니다:

-- PostgreSQL
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
-- ... 모든 INSERT 문 ...
COMMIT;

이후 검사를 다시 활성화해 앞으로의 쓰기가 계속 검증되도록 합니다. 이 방법은 동작하지만 순서 문제를 가릴 뿐입니다. 덤프가 부분적이라면 여전히 고아 행이 남을 수 있습니다.

해결책 3: DumpCleaner로 두 가지를 자동으로 처리하기

DumpCleaner는 덤프를 읽어 CREATE TABLEALTER TABLE에서 모든 외래 키를 추출하고, 의존 관계 그래프를 만들어, 바로 가져올 수 있는 깔끔한 파일을 내보냅니다:

  1. .sql 덤프를 DumpCleaner에 끌어다 놓습니다 (MySQL, MariaDB, PostgreSQL, SQLite 또는 MS SQL).
  2. INSERT 순서 → 의존 관계 기준 (FK 인식)을 선택합니다. 위상 정렬을 통해 부모가 자식보다 먼저 자동으로 배치됩니다.
  3. 원한다면 외래 키 검사 비활성화를 체크합니다. 사용하는 데이터베이스에 맞는 올바른 문으로 출력을 감싸 줍니다.
  4. 내보내기. 새 파일을 가져오면 제약 조건 오류가 사라집니다.

심지어 순환 외래 키를 감지해 불가능한 순서를 만들어 내는 대신 경고해 줍니다.

더 이상 수동 INSERT 수술은 없다

DumpCleaner는 크기에 상관없이 어떤 파일이든 외래 키 의존 관계에 따라 INSERT를 재정렬합니다. 스트리밍 방식으로 일정한 메모리만 사용합니다. 네이티브 macOS & iPadOS 앱, 한 번 구매로 끝.

App Store에서 다운로드

자주 묻는 질문

가져오기 시 "a foreign key constraint fails"가 왜 발생하나요?

덤프가 INSERT를 외래 키 의존 관계가 아니라 알파벳순이나 생성 시간순으로 정렬하기 때문에, 아직 삽입되지 않은 부모 행을 자식 행이 참조하게 됩니다.

가져오기 중 외래 키 검사를 비활성화해도 안전한가요?

완전하고 정합성이 보장된 덤프라면 안전합니다. 원본 데이터베이스에서 이미 유효했던 데이터의 검증만 건너뛰는 것이기 때문입니다. 이후 검사를 다시 활성화하세요.

파일을 손으로 편집하지 않고 INSERT를 재정렬하려면 어떻게 하나요?

DumpCleaner가 외래 키를 감지하고 의존 관계 그래프를 만들어 INSERT를 위상 정렬 순서로 내보냅니다. 그래서 부모가 항상 자식보다 먼저 로드됩니다.

PostgreSQL에서도 동작하나요?

네. DumpCleaner는 pg_dump 출력을 지원하며, 의존 관계 순서 정렬은 물론 SET CONSTRAINTS ALL DEFERRED도 내보낼 수 있습니다.

FK 골칫거리 없이 덤프 가져오기

끌어다 놓고, 의존 관계로 재정렬하고, 내보내기. DumpCleaner가 외래 키를 처리해 주므로 가져오기가 그냥 됩니다.

App Store에서 다운로드