-
nestjs, typeorm-extension을 사용한 seeding공부하기/node.js 2023. 2. 22. 03:34
https://github.com/tsCalm/new-nest-survey/tree/seeder
위 이미지의 빨간 박스를 친 부분에 대한 seeding 작업을 진행합니다.
개념
- Seeder
- 데이터베이스에 데이터를 삽입하는 방법 중 하나
- 개발자들이 원하는 데이터를 자동으로 생성하고 데이터베이스에 추가할 수 있는 프로그램
- Seeder는 일반적으로 데이터베이스 구성 파일과 함께 사용
- 개발자들은 Seeder를 실행하여 데이터를 자동으로 생성 및 삽입할 수 있다
- Seeding
- Seeder를 실행하는 프로세스
- 개발자들은 Seeder를 실행하여 데이터를 자동으로 생성하고 데이터베이스에 삽입
- 이를 통해 애플리케이션이 실행될 때 일관성 있는 데이터가 생성되며, 개발 및 테스트 작업이 더욱 쉬워짐
계획
- survey(설문지)를 3천개 생성한다.
- 하나의 survey(설문지)는 5개의 question(질문)을 갖는다.
- 하나의 question(질문)은 4개의 option(선택지)을 갖는다.
1. 먼저 루트 경로에 data-soruce.ts 파일을 선언합니다.
*2023-02-27 -> data-source.ts 파일을 만들면 dist/main.ts가 존재하지 않음*
import { ConfigService } from '@nestjs/config'; import { config } from 'dotenv'; import { DataSource, DataSourceOptions } from 'typeorm'; import { SeederOptions } from 'typeorm-extension'; config( // 외부 데이터베이스에 연결하려면 아래 주석을 해제하고 .env파일 경로를 입력하세요 //{ path: 'ENV파일주소' } ); const configService = new ConfigService(); const option: DataSourceOptions & SeederOptions = { 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_NAME'), synchronize: false, logging: true, entities: ['src/**/*.entity.ts'], seeds: ['src/**/seed/*.ts'], factories: ['src/**/factory/*.ts'], // migrations: ['src/database/migrations/*.ts'], // migrationsTableName: 'migrations', }; export default new DataSource(option);
-> @nestjs/config 모듈을 사용하고 있기 때문에 ConfigService를 호출해서 datasoruce 파일을 만들어 주었습니다.
만약 @nestjs/config 모듈을 사용하고 있지 않다면 process.env.DB_HOST등으로 바꿔서 사용하시면 됩니다.
2. package.json에 seed 명령을 추가합니다.
"scripts": { ... "seed": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-extension/dist/cli/index.js seed", ... },
3. seed-data/seed/index.ts
import { Survey } from 'src/survey/survey.entity'; import { DataSource } from 'typeorm'; import { Seeder } from 'typeorm-extension'; export default class RootSeeder implements Seeder { async run(dataSource: DataSource): Promise<any> { const repository = dataSource.getRepository(Survey); await repository.insert([ { name: '테스트 설문지', description: '설문지 설명입니다. 성실한 답변 부탁드립니다.', }, ]); } }
4. 터미널에서 npm run seed 명령을 실행합니다. 아래는 결과입니다.
5. 이제 factory를 생성한 후 faker.js를 사용하여 동적으로 데이터를 넣어보도록 하겠습니다.
seed-data/factory/survey.factory.ts
import { setSeederFactory } from 'typeorm-extension'; import { Survey } from '../../survey/survey.entity'; export default setSeederFactory(Survey, (faker) => { const survey = new Survey(); survey.name = faker.lorem.lines(1); survey.description = faker.lorem.lines(3); return survey; });
6. seed-data/seed/index.ts
import { Survey } from 'src/survey/survey.entity'; import { DataSource } from 'typeorm'; import { Seeder, SeederFactoryManager } from 'typeorm-extension'; export default class RootSeeder implements Seeder { async run( dataSource: DataSource, factoryManager: SeederFactoryManager, ): Promise<any> { const userFactory = factoryManager.get(Survey); // 시드 데이터를 1개만 저장하고 싶은 경우 사용 // await userFactory.save(); // 시드 데이터를 여러개 저장하고 싶은 경우 사용 const surveyList = await userFactory.saveMany(5); console.log(surveyList); } }
결과
7. seed-data/factory/question.factory.ts
import { setSeederFactory } from 'typeorm-extension'; import { Question } from '../../question/question.entity'; export default setSeederFactory(Question, (faker) => { const question = new Question(); question.text = faker.lorem.lines(1); question.type = 'number'; return question; });
8. seed-data/factory/option.factory.ts
import { setSeederFactory } from 'typeorm-extension'; import { Option } from '../../option/option.entity'; export default setSeederFactory(Option, (faker) => { const option = new Option(); option.text = faker.lorem.word(); return option; });
9. seed-data/seed/index.ts
import { Option } from 'src/option/option.entity'; import { Question } from 'src/question/question.entity'; import { Survey } from 'src/survey/survey.entity'; import { DataSource } from 'typeorm'; import { Seeder, SeederFactoryManager } from 'typeorm-extension'; export default class RootSeeder implements Seeder { async run( dataSource: DataSource, factoryManager: SeederFactoryManager, ): Promise<any> { const surveyFactory = factoryManager.get(Survey); const questionFactory = factoryManager.get(Question); const optionFactory = factoryManager.get(Option); const surveyList = await surveyFactory.saveMany(3000); let questionPendingList = []; let optionPendingList = []; for (const survey of surveyList) { [1, 2, 3, 4, 5].forEach((num) => { const newQuestion = questionFactory.save({ survey_id: survey.id, question_number: num, }); questionPendingList.push(newQuestion); }); } const questionList = await Promise.all(questionPendingList); for (const question of questionList) { [1, 2, 3, 4].forEach((num) => { const newOption = optionFactory.save({ question_id: question.id, option_number: num, }); optionPendingList.push(newOption); }); } await Promise.all(optionPendingList); } }
결과
survey
question
option
'공부하기 > node.js' 카테고리의 다른 글
NestJs TypeOrm MySql Entity Name Error (0) 2023.02.24 MySql [ Like, Full Text Index ] 테스트 (0) 2023.02.24 4. NestJs & Hexagonal - [ 테스트 ] - 실패하는 테스트가 성공하도록 최소한으로 구현하기 (0) 2023.02.14 3. NestJs 설문조사 미니 프로젝트 - [ 테스트 ] - 실패하는 테스트 케이스 (0) 2023.02.14 2. NestJs & Hexagonal - [ ports ] (0) 2023.02.12 - Seeder