[Project] Nest seeding 해보기 (typeorm-extension사용)
시작하며
nest 프로젝트를 진행하면서 페이지네이션과 DB의 성능 측정 및 다양한 기능을 확인해 가며 개발을 하고 싶다는 생각을 하던 도중, seeding(무작위 데이터)를 삽입함으로써 개발을 한다는 사실을 알게 되었습니다. nest에서 typeorm-seeding과 typeorm-extension을 사용해서 seeding을 할 수 있다는 사실을 알게 되었습니다.
마주친 문제
처음 seeding을 구현할 때, typeorm-seeding를 활용했습니다. 하지만 TypeORM버전 0.3.x이후로부터 deprecated 되었다는 것을 알게 되었습니다. 구글링을 통해 알아본 결과 TypeORM0.3.x이후 버전부터 typeorm-extenstion을 사용한다는 내용을 확인 후, 다시 typeorm-extenstion을 사용한 seeding을 기록해보려 합니다.
참고 -> 현재 날짜 기준으로 typeorm-seeding는 3년째 업데이트 사항이 없으나, typeorm-extension은 한 달 전에 업데이트 사항이 있음
- typeorm-extension: https://github.com/tada5hi/typeorm-extension
typeorm-extension 패키지를 통해 seeding 셋업을 진행해 보겠습니다.
npm install typeorm-extension --save
package.json의 script에 아래 스크립트를 넣습니다.
"seed": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-extension/dist/cli/index.js seed"
typeorm-extension cli의 경우 절대경로를 이해하지 못한다고 합니다. (tsconfig-paths 패키지 활용)
이제 루트 디렉토리에 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: 'localhost',
port: 10500,
username: 'root',
password: process.env.DB_PWD,
database: 'linkfriends_local',
synchronize: false,
entities: ['src/**/*.entity.ts'],
})
이제 생성하고 싶은 초기 데이터 삽입을 위해 src/database폴더를 추가하고 src/database에서 factories와 seeds폴더를 각각 생성해 줍니다.(제세한 내용은 아래에서 설명하겠습니다.)
src/database/seeds에 products.seeds.ts를 추가합니다.
import { Product } from 'products/entities/product.entity'
import { DataSource } from 'typeorm'
import { Seeder, SeederFactoryManager } from 'typeorm-extension'
export default class ProductSeeder implements Seeder {
async run(
dataSource: DataSource,
factoryManager: SeederFactoryManager,
): Promise<any> {
const repository = dataSource.getRepository(Product)
const productsFactory = factoryManager.get(Product)
await productsFactory.saveMany(50)
}
}
이제 Faker, Factory를 활용해서 내가 커스텀한 데이터를 여러 개 넣을 수 있도록 src/database/factories에 products.factory.ts파일을 추가합니다.
import { Product } from 'products/entities/product.entity'
import { setSeederFactory } from 'typeorm-extension'
import { Faker } from '@faker-js/faker'
import { User } from 'users/entities/user.entity'
export default setSeederFactory(Product, (faker: Faker) => {
const user = new User()
user.mallId = 'whitecircle1'
const product = new Product()
product.id = faker.string.uuid()
product.createdAt = faker.date.recent()
product.shopNo = '1' //faker.number.int({ min: 1, max: 100 }) + ''
product.productNo = faker.number.int({ min: 1, max: 100 }) + ''
product.productCode = `${faker.string.alpha()}${faker.number
.int({ max: 999999 })
.toString()
.padStart(6, '0')}${faker.string.alpha()}`
product.productName = faker.word.noun(10)
product.price = faker.commerce.price({ min: 1000, max: 1000000 })
product.detailImage = faker.image.urlPicsumPhotos()
product.listImage = faker.image.urlPicsumPhotos()
product.tinyImage = faker.image.urlPicsumPhotos()
product.smallImage = faker.image.urlPicsumPhotos()
product.user = user
return product
})
Faker의 사용법은 생략할 것이며, 참고할 주소는 아래에 남겨두겠습니다.
이제 CLI 명령어를 통해서 데이터를 생성해 보겠습니다.
npm sun seed
위 캡처사진을 보면 데이터가 잘 들어간 것을 확인할 수 있습니다.
마치며
이번 포스트를 통해 2가지를 배웠습니다.
첫 째, 내가 사용할 라이브러리의 다운로드 횟수 또는 지속적인 업데이트가 이루어지는지 확인하고 개발을 해야 한다는 점.
지속적인 업데이트가 없다면 해당 라이브러리를 사용하는 유저들이 적어지며, 또한 issue들이 계속해서 해결되지 않고 있을 확률이 높습니다. 즉, 안정성이 떨어지며 신뢰도가 떨어질 수 있다는 점입니다.
둘째, 개발은 나혼자 하는 게 아니다는 점.
지금 진행 중인 프로젝트에서 데이터를 넣으려면 카페 24의 임시 쇼핑몰로 들어가 데이터를 하나하나 생성해야 하는 번거로움이 있었고, 다른 팀원 분들도 저와 같은 불편함을 느낄 수 있다고 생각했습니다. 내가 필요한 기능은 곧 팀원들이 필요한 기능일 수 있다고 느꼈습니다.
혼자가 아니라 다같이 소통하며 불편한 점을 서로서로 해결해 나가는 개발자가 되고 싶습니다.