Как делать миграции и сиды БД в nestjs?

Всем привет.

Начал детальнее изучать nodejs вместе с nestjs. Как тут можно делать миграции и сиды(seeds), какой подход используется(как принято)? Есть опыт работы на php-Larave


Ответы (2 шт):

Автор решения: Dia TM

Я тоже на ларке сидел. По поводу сидов не знаю, но хочу попробовать пакет в npm faker js:

TypeORM Tutorial: Migrations, queries, and more! | NestJS youtube

10 - Faking the user data via Faker.js ~ Nest.js youtube

{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "root",
  "password": "root",
  "database": "app1",
  "entities": ["dist/**/*.entity{.ts,.js}"],
  "synchronize": false, //true будет автоматически создавать таблицы в бд
  "migrations": ["dist/migrations/*{.ts,.js}"],
  "cli": {
    "migrationsDir": "src/migrations"
  }
}
"scripts": {
    "typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js",
    "migrate:run": "npm run build && npm run typeorm migration:run",
    "migrate:generate": "npm run build && npm run typeorm migration:generate -- -n",
    "migrate:create": "npm run build && npm run typeorm migration:create -- -n",
    "migrate:revert": "npm run build && npm run typeorm migration:revert",
    "migrate:show": "npm run build && npm run typeorm migration:show",
    "migrate:drop": "npm run build && npm run typeorm schema:drop",
    "migrate:fresh": "npm run build && npm run typeorm schema:drop && npm run typeorm migration:run"
  },

запуск

npm run migrate:generate tablename
npm run migrate:create tablename
npm run migrate:run
npm run migrate:revert
npm run migrate:show
npm run migrate:drop
npm run migrate:fresh
→ Ссылка
Автор решения: ashura

про миграции вам уже ответили, так что напишу про сидеры. в моём примере я делаю сидер для таблицы typesOfAppeal в момент OnModuleInit. естественно, код размещен в appeal.module.ts.

export class AppealModule implements OnModuleInit {
    private readonly tableNames = ['types_of_appeal'];

    constructor(
        @InjectRepository(TypeOfAppealEntity)
        private readonly typeOfAppealRepository: Repository<TypeOfAppealEntity>,
        private readonly connection: DataSource,
    ) { }
    async onModuleInit() {
        try {
            const tablesExist = await this.checkTablesExistence();
            if (!tablesExist) {
                await seedTypeOfAppeal(this.typeOfAppealRepository);
                Logger.log('TypesOfAppeal inserted successfully');
            } else {
                Logger.log('TypesOfAppeal already exist. Skipping seeding');
            }
        } catch (error) {
            Logger.error('Error seeding typesOfAppeal:', error);
        }
    }

    private async checkTablesExistence(): Promise<boolean> {
        try {
            const hasDataPromises = this.tableNames.map(async (tableName) => {
                const count = await this.connection.manager.count(tableName);
                return count > 0;
            });

            const hasDataResults = await Promise.all(hasDataPromises);

            return hasDataResults.some((hasData) => hasData);
        } catch (error) {
            Logger.error('Error checking table existence:', error);
            return false;
        }
    }

}

мой seedTypeOfAppeal выглядит вот так, причём это пример для mysql, для mongo тоже есть, там несколько по-другому выглядит. Этот код размещен в seeds-папке:

export async function seedTypeOfAppeal(typeOfAppealRepository: Repository<TypeOfAppealEntity>) {
    const data = [
        { name: AppealType.AddIndividualMeter },
        { name: AppealType.VerifyIndividualMeter },
        { name: AppealType.Claim },
        { name: AppealType.ProblemOrQuestion },
    ];

    for (const item of data) {
        const typeOfAppeal = typeOfAppealRepository.create(item);
        await typeOfAppealRepository.save(typeOfAppeal);
    }
}
→ Ссылка