TypeORM Seeding을 통한 DB 시딩(Seeding)

기존에 faker.js를 사용해서 Seeding용 API 엔드포인트를 구성하였었는데 해당 Faker 모듈이 관리가 안되는 이슈도 있고, request한 유저의 권한을 valid하긴 하지만, 데이터 베이스에 직접적으로 영향을 줄 수 있는 엔드포인트가 외부로 노출되어있는 점이 불안해서 typeorm seeding을 통해 ssh로 직접 서버에 접속해서 커맨드를 날리는 방향으로 변경하였다.

 

Faker.js를 통한 Seed API 작성

백엔드를 개발하다보면 REST API의 GET 메소드에서 DB에서 데이터를 제대로 불러오는지 확인해야하는데 이럴 때 Seed API를 통해 테스트 용도의 fake DB를 구성하는 것이 매번 데이터를 직접 입력해넣

eight20.tistory.com

 

기존의 Faker 문서는 없어지고, What really happend with Aaron Swartz? 라는 말만 Readme에 적혀있다.

 

NestJS와 관련된 Seeding에는 nestjs-seeder가 있었지만, 한 개는 버전이 0.2.1이고, 다른 하나는 2년전을 마지막으로 유지보수가 되지않아 선택하지 않았다. NestJS쪽 Seeding 라이브러리가 마땅찮아서 TypeORM과 관련된 Seeding 라이브러리를 찾아보니 typeorm-seeding 이라는 라이브러리가 있는데 NestJs 관련 Seeding 라이브러리에 비해 버전도 1.6.1이고, 월간 사용자도 6만명 후반대여서 해당 라이브러리를 이용해보기로 하였다.

 

typeorm-seeding, @types/faker 총 2개의 라이브러리를 설치하면 된다. 

$ npm i typeorm-seeding
$ npm i -D @types/faker

해당 라이브러리를 사용하려면 typeorm의 설정 파일인 ormconfig.js 혹은 ormconfig.json이 필요하다. 예시는 ormconfig.js를 기준으로 진행하였다. 프로젝트를 모노레포로 관리하는 경우에도 동일하게 파일이 위치한 디렉토리를 작성하면 된다.

// ormconfig.js
module.exports = {
  ...
  // seed 파일이 어디에 위치해있는지 지정한다. 
  // 현재 위치는 src안의 seeds 파일 안의 디렉토리 안의 .js 혹은 .ts 확장자 파일들이다.
  seeds: ['src/seeds/**/*{.ts,.js}'], 
  factories: ['src/factories/**/*{.ts,.js}'], 
}

 

typeorm-seeding 라이브러리의 seed관련 cli를 사용하려면 package.json 안에 스크립트를 추가해야한다.

"scripts": {
  "seed:config": "ts-node ./node_modules/typeorm-seeding/dist/cli.js config", // seed 설정 체크
  "seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed", // seed 실행
  ...

}

 

기본적인 seeder는 typeorm-seeding의 Seeder를 implements해서 작성한다.

❗️*.seeder.ts가 여러 개일 때 알파벳 순으로 실행됩니다. Ex) admin.seeder.ts가 user.seeder.ts보다 먼저 실행됨 
// user.seeder.ts
export default class UserSeeder implements Seeder {
    public async run(factory: Factory, connection: Connection):Promise<void> {
        await connection
          .createQueryBuilder()
          .insert()
          .into(User) // values 메소드에 입력한 데이터를 insert할 테이블이 매핑된 entity class 이름
          .values([
            {
              email: 'test1@test.com',
              password: hashSync('test1234'),
              phoneNumber: '01000000000',
              name: 'TestUser1',
              role: Role.USER,
            },
            {
              email: 'test2@test.com',
              password: hashSync('test1234'),
              phoneNumber: '01000000000',
              name: 'TestUser2',
              role: Role.USER,
            }
          ])
         .execute();
    }
}

 

seeding을 할 때, 미리 필요한 정보들을 입력해놓고, seed 커맨드를 통해 해당 정보들을 DB로 밀어넣는 경우와 테스트용 랜덤한 정보가 필요할 때 seed를 통해 해당 정보를 DB로 밀어넣는 경우에는 코드상에서 차이가 존재한다.

 

지정한 정보를 밀어넣는 경우에는 factory가 아닌 connection을 사용해서 values 메소드 안에 데이터들을 미리 작성해두어야한다. 이와 다르게 랜덤한 정보를 밀어넣는 경우에는 factory 파일을 통해 랜덤하게 데이터를 생성하여 seed에 리턴한다.

 

scripts를 추가한 package.json이 위치한 디렉토리에서 npm run seed:config를 통해 ormconfig.js의 설정이 제대로 적용되었는지 체크해볼 수 있다.

seed:config 커맨드를 통해 설정이 적용되고 있는지 확인해볼 수 있다.