typeorm-extension으로 데이터 seeding하기

0
npm i typeorm-extension

type-orm으로 데이터를 seed 해보자.

원래는 typeorm-seeding, typeorm-model-generator이였지만 typeorm이 0.3 version이 되면서 지원하지 않게 되었다. 따라서 typeorm-extension 을 사용하도록 하자.


ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:run  -d src/data-source.ts

그리고 해당 명령어를 실행시켜주면 되는데 typeorm-extension 은 database/seeds 폴더 안에 있는 ts파일들을 인식하여 작동한다.


import { Seeder, SeederFactoryManager } from 'typeorm-extension';
import { DataSource } from 'typeorm';
import { User } from './user';

export default class UserSeeder implements Seeder {
    public async run(
        dataSource: DataSource,
        factoryManager: SeederFactoryManager
    ): Promise<any> {
        const repository = dataSource.getRepository(User);
        await repository.insert([
            {
                firstName: 'Caleb',
                lastName: 'Barrows',
                email: 'caleb.barrows@gmail.com'
            }
        ]);
    }
}

따라서 database/seeds/seed.ts 파일을 위처럼 작성해주면 된다.


Factory로 faker.js사용하기

하지만 node.js에서 seed 했던 것처럼 npm에는 유명한 faker.js 라이브러리가 존재한다.

typeorm-extension는 faker.js라이브러리를 내포하고 있어 따로 설치하지 않아도 사용할 수 있다.

대신 faker.js를 사용하려면 factory를 사용하라고 typeorm-extension 문서에 나와있다.


import { setSeederFactory } from 'typeorm-extension';
import { UserEntity } from '../../entities/user.entity';

export default setSeederFactory(UserEntity, (faker) => {
  const user = new UserEntity();
  user.snsId = faker.string.uuid();
  user.nickname = faker.internet.userName();
  user.name = faker.person.fullName();
  user.birthday = getRandomDate();
  user.bank = 'Hana';
  user.account = faker.finance.accountNumber();
  user.profileImgSrc = faker.image.avatar();
  user.fcmId = faker.string.uuid();
  user.alarm = true;

  return user;
});

이렇게 factory에서 user를 만들고 return 한 다음



import { Seeder, SeederFactoryManager } from 'typeorm-extension';
import { DataSource } from 'typeorm';

export default class mySeeder implements Seeder {
    public async run(
        dataSource: DataSource,
        factoryManager: SeederFactoryManager
    ): Promise<any> {
        const userFactory = factoryManager.get(UserEntity);
				const users = await userFactory.saveMany(100);
    }
}

seed파일에서 위처럼 factory를 가져와 저장하면 된다.

typeorm-extension 은 database/factories 폴더 안에 있는 ts파일들을 자동으로 factory로 인식하기 때문에 따로 userFactory를 import하지 않아도 된다.

entity마다 factory를 만들어서 seed하도록 하자.


관계 설정은 어떻게 하지?

하지만 이렇게 entity마다 factory 파일을 만들기 때문에 관계 설정에서 어려움을 겪을 수 있다.

예를 들어 post

import { setSeederFactory } from 'typeorm-extension';
import { PostEntity} from '../../entities/post.entity';

export default setSeederFactory(PostEntity, (faker) => {
  const post = new PostEntity();
  post.comment = faker.lorem.sentence();
	post.User // ???

  return post;
});

위 처럼 post에 faker를 사용하여 게시글을 임의로 만들었는데, 어떤 user의 게시글인지는 어떻게 표현할까?


import { Seeder, SeederFactoryManager } from 'typeorm-extension';
import { DataSource } from 'typeorm';

export default class mySeeder implements Seeder {
    public async run(
        dataSource: DataSource,
        factoryManager: SeederFactoryManager
    ): Promise<any> {
				const postRepository = dataSource.getRepository(PostEntity);

        const userFactory = factoryManager.get(UserEntity);
				const postFactory = factoryManager.get(PostEntity);

				const post = await postFactory.make({
          User: user,
        });

				await postRepository.save(post);
    }
}

그럴땐 이처럼 특정 column만 factory로 만들고, seed파일에서 make 메서드를 사용하여 user를 넣어 관계를 삽입해 주면 된다.

그리고 postRepository로 직접 save를 해주어야 한다.

profile
https://www.youtube.com/watch?v=__9qLP846JE

0개의 댓글

관련 채용 정보