본문 바로가기

이노베이션캠프/TIL

자바스크립트 데이터 외부 DB로 보내기

어제는 구글 스프레드시트 데이터를 JSON 파일로 변환하는 과정을 마쳤고, 오늘은 이 데이터를 DB에 업로드하는 로직을 작성했다.

 

1. JSON 데이터 로드

스프레드시트에서 변환한 JSON 파일을 한 번에 읽어오기 위해 Promise.all을 사용했습니다. 읽어온 데이터는 gameAssets 객체에 담아 관리합니다.

export const loadGameAssets = async () => {
  try {
    const [CharacterInfo, Item, LevelInfo, MonsterInfo, Stage, Monster, MonsterOnStage] =
      await Promise.all([
        readFileAsync('CharacterInfo.json'),
        readFileAsync('Item.json'),
        readFileAsync('LevelInfo.json'),
        readFileAsync('MonsterInfo.json'),
        readFileAsync('Stage.json'),
        readFileAsync('Monster.json'),
        readFileAsync('MonsterOnStage.json'),
      ]);

    gameAssets = { CharacterInfo, Item, LevelInfo, MonsterInfo, Stage, Monster, MonsterOnStage };
    return gameAssets;
  } catch (err) {
    throw new Error('Failed to load game assets: ' + err.message);
  }
}

2. 업로드 쿼리 준비

모든 데이터를 DB 테이블별로 분리해 upsert할 수 있도록 빈 queries 배열을 만들었습니다.

const queries = [];

for (const [tableName, rows] of Object.entries(gameAssets)) {
  if (!rows || rows.length === 0) continue;
  queries.push(...(await upsertTable(tableName, rows.data)));
}

3. 업서트 로직

tableMap을 통해 JSON의 키와 Prisma 모델을 연결한 후, upsertTable 함수에서 각 row를 upsert하도록 구현했습니다.
특히 MonsterOnStage 테이블은 복합 키(monsterId, stageId)를 기준으로 upsert 하도록 분기처리했습니다.

 

const tableMap = {
  CharacterInfo: prisma.characterInfo,
  MonsterInfo: prisma.monsterInfo,
  Item: prisma.item,
  Stage: prisma.stage,
  LevelInfo: prisma.levelInfo,
  Monster: prisma.monster,
  MonsterOnStage: prisma.monsterOnStage,
};

async function upsertTable(tableName, data) {
  const model = tableMap[tableName];
  if (!model) throw new Error(`${tableName} 매핑된 모델 없음`);

  return data.map((row) => {
    const where =
      tableName === 'MonsterOnStage'
        ? { monsterId_stageId: { monsterId: row.monsterId, stageId: row.stageId } }
        : { id: row.id };

    return model.upsert({
      where,
      update: { ...row },
      create: { ...row },
    });
  });
}

 

4. 트랜잭션 실행

마지막으로 queries 배열을 한 번에 트랜잭션 처리하여 DB에 업로드합니다.

export async function updateAllGameAssets() {
  ...
  await prisma.$transaction(queries);
  console.log('모든 정적 테이블 업데이트 완료');
}

 

 

결론

오늘은 구글 스프레드시트 데이터를 JSON으로 변환한 뒤, 이를 Prisma를 이용해 DB에 일괄 업로드하는 로직을 작성했습니다.
핵심 포인트는 다음과 같습니다.

  1. Promise.all을 이용해 여러 JSON 파일을 병렬적으로 읽어오기
  2. Object.entries로 테이블별 데이터를 분리
  3. upsertTable 함수에서 Prisma 모델을 매핑하고, id 혹은 복합 키를 기준으로 upsert 처리
  4. 모든 쿼리를 $transaction으로 묶어 일괄 실행

이를 통해 스프레드시트에서 관리하는 정적 데이터를 안전하고 일관성 있게 DB로 반영할 수 있었습니다.