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 파일을 위처럼 작성해주면 된다.
하지만 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를 해주어야 한다.