참고
- typeorm-extension docs
- https://min-nine.tistory.com/80
- https://github.com/tada5hi/typeorm-extension
- https://github.com/myvoltron/typeorm-seeding
Seeder란?
데이터베이스에 초기 데이터 및 테스트 용 더미 데이트를 입력해주는 도구입니다.
- 권한 정보나 관리자 계정같은 데이터는 초기에 필요한 정보인데 이를 Seeder를 사용해서 미리 입력할 수 있습니다.
- 테스트할 때 필요한 데이터들을 편리하게 채워넣을 수 있습니다.
우선 셋업을 설명하기 전에, 보통 TypeORM Seeding을 위해서 구글링을 해보면 typeorm-seeding
이라는 패키지를 사용한다는걸 알 수 있습니다. 하지만 두 가지 이유로 비추천합니다.
- 더 이상 관리되고 있지 않음: 여기에서 확인해보시면 마지막 업데이트가 3년전입니다.
- 따라서 여전히 ormconfig를 사용해야함: dataSource 사용이 좀 더 권장됩니다. 왜 ormconfig를 쓰면 안되는지는 여기에서 확인하실 수 있습니다.
그래서 제가 찾아본 패키지는 typeorm-extension
이라는 패키지입니다.
- https://www.npmjs.com/package/typeorm-extension
- 지속적으로 관리되고 있습니다. - 2023년 2월 12일 기준으로 한달 전까지 업데이트가 있었군요!
- TypeORM 공식문서에도 소개되어있습니다! - 여기를 보시면 확인하실 수 있습니다. 신뢰도가 상승하는군요…
- dataSource를 사용합니다.
TypeORM Seeding 셋업 및 실행
TypeORM Migration 을 읽고 오셨다는 가정하에 진행됩니다.
typeorm-extension
패키지를 통해 seeding 셋업을 진행해봅시다.
npm install typeorm-extension --save
package.json
의 scripts
섹션에 다음 스크립트를 넣습니다.
"seed": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-extension/dist/cli/index.js seed",
typeorm-extension
cli의 경우에도 절대경로를 이해하지 못해서 tsconfig-paths
패키지를 활용한 모습입니다.
- typeorm-extension은
DataSource
파일의 디폴트 경로로 루트 디렉토리의data-source.ts
파일을 찾습니다. 따로 지정할 수 있습니다.
- typeorm-extension의 seed 명령어는 seeder 파일의 디폴트 경로를src/database/seeds/**/*{.ts,.js}
로 간주합니다. 따로 지정할 수 있습니다.
typeorm-extension 패키지도 typeorm의 dataSource를 사용하기 때문에 data-source.ts
가 필요할거같네요. 루트 디렉토리에 추가했습니다.
import { ConfigService } from '@nestjs/config';
import { config } from 'dotenv';
import { DataSource } from 'typeorm';
config();
const configService = new ConfigService();
export default new DataSource({
type: 'mysql',
host: configService.get('DB_HOST'),
port: configService.get<number>('DB_PORT'),
username: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_DATABASE'),
synchronize: false,
entities: ['src/**/*.entity.ts'],
migrations: ['src/database/migrations/*.ts'],
migrationsTableName: 'migrations',
});
이제 우리의 Cat Entity에 대한 초기 데이터 삽입을 위해서 src/database/seeds
경로에 cats.seeder.ts
파일을 추가합니다.
해당 파일에서 어떤 데이터를 넣을지 정의하면 됩니다.
import { Cat } from 'src/cats/entities/cat.entity';
import { DataSource } from 'typeorm';
import { Seeder } from 'typeorm-extension';
export default class CatsSeeder implements Seeder {
async run(dataSource: DataSource): Promise<any> {
const repository = dataSource.getRepository(Cat);
await repository.insert([
{
name: 'cat1',
kind: 'cat',
},
]);
}
}
보시다시피, typeorm-extension의 Seeder를 구현했습니다. 그리고 내부적으로 DataSource
를 주입받고 repository를 사용해서 실제 데이터를 입력하는 방식으로 진행된다는걸 알 수 있습니다.
이제 터미널에서 다음 명령어를 실행합니다.
npm run seed
다음과 비슷한 화면이 나오면 성공한겁니다.
따로 성공했다는 메시지는 없습니다.
실제로 데이터가 잘 들어갔는지 확인하기 위해, MySQL Workbench로 확인해봤습니다.
잘 들어갔네요.
랜덤 데이터 삽입하기 feat. Faker, Factory
위의 과정에서는 우리가 임의로 정한 데이터만 삽입하는 과정이였고 랜덤한 데이터가 입력되게 하고 싶을 수도 있습니다.
typeorm-extension에서는 factory라는 기능을 통해서 랜덤한 데이터를 입력할 수 있습니다.
src/database/factories
디렉토리에 cats.factory.ts
파일을 추가합니다.
typeorm-extension은 factory 파일의 디폴트 디렉토리를
src/database/factories
로 간주합니다. 따로 지정할 수 있습니다.
import { Cat } from 'src/cats/entities/cat.entity';
import { setSeederFactory } from 'typeorm-extension';
export default setSeederFactory(Cat, (faker) => {
const cat = new Cat();
cat.name = faker.name.fullName();
cat.kind = faker.animal.cat();
return cat;
});
cats.seeder.ts
의 코드를 수정합니다.
import { Cat } from 'src/cats/entities/cat.entity';
import { DataSource } from 'typeorm';
import { Seeder, SeederFactoryManager } from 'typeorm-extension';
export default class CatsSeeder implements Seeder {
async run(
dataSource: DataSource,
factoryManager: SeederFactoryManager,
): Promise<any> {
const repository = dataSource.getRepository(Cat);
// await repository.insert([
// {
// name: 'cat1',
// kind: 'cat',
// },
// ]);
const catsFactory = factoryManager.get(Cat);
await catsFactory.saveMany(5);
}
}
SeederFactoryManager
를 주입받아서 다음과 같은 동작을 합니다.
get
메서드를 통해서 Entity에 관련된 factory를 얻습니다. 해당 Entity와 관련된 factory가src/database/factories
에 존재해야합니다.saveMany
메서드를 통해 원하는 개수만큼 랜덤 데이터를 입력할 수 있습니다.
이후 npm run seed
명령어를 실행하고나서 DB를 보면 랜덤한 데이터가 생성되어 있는 것을 보실 수 있습니다.
5번부터 9번까지 랜덤하게 생성된것을 느낄 수 있습니다.
그 외
- typeorm-extension 공식문서를 보시면 아시겠지만 굳이 Seeding 뿐만 아니라 다양한 용도로 쓸 수 있습니다. 직접 확인해보세요