본문 바로가기
기억 저장소

[TypeORM] Cannot add or update a child row: a foreign key constraint fails 오류 해결

by halls99 2022. 10. 9.

😱 원인

 

에러 메시지 그대로 외래 키 제약을 코드 상에서 어겼기 때문에 발생한 에러이다.

 

 

🔥 해결 과정

 

item.json 파일의 데이터를 item, item_info 총 2개의 테이블에 나누어 저장하고자 하였다.

 

item 테이블과 item_info 테이블은 id라는 column으로 외래 키 제약을 걸어 일대일 대응 테이블을 구성한 상태에서

 

TypeORM의 Repository로 두 테이블을 불러와, 불러온 json 데이터를 쪼개어 각각 save 한다.

 

 

// json 파일을 불러와 변수에 저장
const itemList = JSON.parse(fs.readFileSync(path.join(__dirname, "/data/item.json"), "utf-8"));

// 이를 순회하며 테이블 2개에 나누어 INSERT
itemList.map((item) => {
  const itemRow = itemRepository.create({
	// datas
  });
  itemRepository.save(itemRow);

  const itemInfoRow = itemInfoRepository.create({
	// datas
  });
  itemInfoRepository.save(itemInfoRow);
});

 

 

하지만 위 코드에서 외래 키 제약을 어겼다는 오류를 발견했고 데이터들을 점검해보았지만 문제를 발견할 수 없었다.

 

그래서 data-source 파일에서 logging: true 옵션을 걸고 쿼리 로그를 보았더니,

 

외래 키의 주도권을 쥐고 있는 item 테이블에 데이터가 먼저 들어가는 것이 아닌,

 

item_info 테이블에 데이터가 먼저 들어가는 경우가 생겨 외래 키 제약을 의도치 않게 어기게 된 것이었다.

 

 

이는 Node의 비동기성으로 발생했기 때문에 async, await 를 넣은 아래 코드를 통해 문제를 해결하였다.

 

// json 파일을 불러와 변수에 저장
const itemList = JSON.parse(fs.readFileSync(path.join(__dirname, "/data/item.json"), "utf-8"));

// 이를 순회하며 테이블 2개에 나누어 INSERT
itemList.map(async (item) => {
  const itemRow = itemRepository.create({
	// datas
  });
  await itemRepository.save(itemRow);

  const itemInfoRow = itemInfoRepository.create({
	// datas
  });
  await itemInfoRepository.save(itemInfoRow);
});

 

 

 

 

 

 

댓글