2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nestjs+typeormでダミーデータを投入する方法

Posted at

いろいろな記事を探してみたが、わかりやすくまとまっているnestjs + typeormでのダミーデータ投入方法の記事がなかった(見つけられなかった)ので、備忘録として残しておきます。

結論

seeder/role.seeder.ts

import { DataSource } from 'typeorm';
import { Seeder } from 'typeorm-extension';
import { Role } from '../user/entities/role.entity';

export class RoleSeeder implements Seeder {
  public async run(dataSource: DataSource): Promise<void> {
    const roleRepository = dataSource.getRepository(Role);

    const rolesList = [
      { roleName: 'admin' },
      { roleName: 'user' },
      { roleName: 'guest' },
    ];

    for (const roleData of rolesList) {
      const existingRole = await roleRepository.findOne({
        where: { roleName: roleData.roleName },
      });

      if (!existingRole) {
        const role = roleRepository.create(roleData);
        await roleRepository.save(role);
      }
    }
  }
}

seeder/seed.helper.ts

// src/seeder/seed.helper.ts
import { DataSource } from 'typeorm';
import { NestFactory } from '@nestjs/core';
import { AppModule } from '../app.module';
import { RoleSeeder } from './role.seeder';

async function runSeeder() {
  const app = await NestFactory.create(AppModule);
  const dataSource = app.get(DataSource);

  // ここにどんどんシーダーを追加していく
  const roleSeeder = new RoleSeeder();
  await roleSeeder.run(dataSource); // シーダーの呼び出し
  // ここまで

  await app.close();
}

runSeeder();

package.json

{
  "scripts": {
    "data:sync": "ts-node -r tsconfig-paths/register ./src/seeder/seed.helper.ts",
  }
}

ポイント

typeorm-extensionを使ったダミーデータの作成は、以下のポイントを抑えると楽かなと思います。

  • DataSourceでリポジトリの取得
  • NestFactoryを使うと凄い楽
  • シーダー追加するのも楽

一つずつ詳細に解説します

DataSourceでリポジトリの取得

RoleSeederで、以下のようなコードが書いてあるのですが…

  public async run(dataSource: DataSource): Promise<void> {
    const roleRepository = dataSource.getRepository(Role);

getRepositoryメソッドでentityクラスを指定するだけで簡単に取ってきてくれます。便利。

NestFactoryを使うと凄い楽

基本的に、シーダーを使うときって、データベースの設定とかを引っ張ってくる必要があるのですが、今回の場合、AppModuleにTypeOrm.forRootで以下のように定義しているので、AppModuleをNestFactory.createメソッドに渡すだけでセットアップが完了してしまいます。

app.module

import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
// その他のインポート部分は省略

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: `.env.${process.env.NODE_ENV || 'development'}.local`,
      isGlobal: true,
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        type: configService.get<'mysql' | 'postgres'>('DB_TYPE'),
        host: configService.get<string>('DB_HOST'),
        port: configService.get<number>('DB_PORT'),
        username: configService.get<string>('DB_USERNAME'),
        password: configService.get<string>('DB_PASSWORD'),
        database: configService.get<string>('DB_DATABASE'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'],
        synchronize: true,
      }),
      inject: [ConfigService],
    }),
    // その他のコードは省略
  ],
})

このようにapp.module.tsを設定している場合、seed.helper.tsで以下のように書くだけ。

  const app = await NestFactory.create(AppModule);

なんと楽なんでしょう。

その他、Factoryを用いてランダムなダミーデータの生成もできるのですが、こちらは余力があったら追記したいと思います。

シーダー追加するのも楽

新たにシーダーを作った場合、以下の部分にどんどん足していけばいいだけです。

  // ここにどんどんシーダーを追加していく
  const roleSeeder = new RoleSeeder();
  await roleSeeder.run(dataSource); // シーダーの呼び出し

  // 例えば新たにuserのシーダー作った場合、以下のように追加する
  const userSeeder = new UserSeeder();
  await userSeeder.run(dataSource);

じゃんじゃんシーダーを追加していきましょう。

多分もっといい方法あるはず…

こんな記事を書いてみたのですが、これが正解とは思ってないですし、もっといい方法があるはずなので、いい方法知っていたら教えてください。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?