javascript - hvordan kan jeg generere en migrasjon ved å bruke TypeOrmModule.forRootAsync som DataSource?


Forsøker å integrere migrasjoner i et nest.js-prosjekt kjørte jeg kommandoen migration:create fra typeorm, og det var ikke noe problem, men når jeg prøver å generere en migrasjon med migration:generate som dette: yarn run typeorm migration:generate ./src/migrations -d ./src/database/database.provider.ts der ./src/migrations er mappen hvor jeg vil ha migrasjonene, og ./src/database/database.provider.ts er hvor jeg har min Datasource som jeg vil vise deg om et øyeblikk, er poenget at jeg fikk følgende feil: `

Error: Given data source file must contain export of a DataSource instance
    at Function.loadDataSource (C:\Proyectos\AmazingDigisignBackend\documents-service-nest\node_modules\src\commands\CommandUtils.ts:49:19)
    at async Object.handler (C:\Proyectos\AmazingDigisignBackend\documents-service-nest\node_modules\src\commands\MigrationGenerateCommand.ts:73:26)
Done in 3.74s.

dette er database.provider.ts:

import {DynamicModule} from "@nestjs/common";
import {ConfigService} from "@nestjs/config";
import {TypeOrmModule} from "@nestjs/typeorm";
import {DataSourceOptions} from "typeorm";

export const DatabaseProvider: DynamicModule = TypeOrmModule.forRootAsync({
  inject: [ConfigService],
  async useFactory(config: ConfigService) {
    return {
      type: 'postgres',
      host: config.get('DATABASE_HOST'),
      username: config.get('DATABASE_USERNAME'),
      password: config.get('DATABASE_PASSWORD'),
      port: config.get('DATABASE_PORT'),
      database: config.get('DATABASE_NAME'),
      autoLoadEntities: true,
      synchronize: false,
      migrations: [__dirname + '/../src/migrations/*{.ts,.js}'],
    } as DataSourceOptions;
  }
})

og dette er min databasemodul:

import {Module} from '@nestjs/common';
import {DatabaseProvider} from './database.provider';

@Module({
  imports: [DatabaseProvider],
  exports: [DatabaseProvider]
})
export class DatabaseModule {
};

Jeg har prøvd å bruke de gamle typeorm-kommandoene som: yarn run typeorm migration:generate -n newMigration . Jeg har sjekket dokumentasjonen hundre ganger, og ingen steder forteller de deg hvordan du genererer en migrasjon ved å bruke typeormmoduleconfig som datasource. Jeg tenkte på å lage en ormconfig.json, men jeg liker det ikke. Hvis ingenting annet fungerer, antar jeg at jeg ikke vil ha mye annet valg.

Svar #1

Filen database.provider.ts som du gir til kommandoen yarn run typeorm migration:generate eksporterer en NestJS dynamisk modul, ikke en DataSource som kan brukes av TypeORM CLI.

Du kan imidlertid legge til en funksjon som bygger DataSource-alternativene i database.provider.ts, og deretter gjenbruke denne funksjonen i en separat fil for å bygge CLI-ens nødvendige konfigurasjon.

I din database.provider.ts :

import {DynamicModule} from "@nestjs/common";
import {ConfigService} from "@nestjs/config";
import {TypeOrmModule} from "@nestjs/typeorm";
import {DataSourceOptions} from "typeorm";

export const DatabaseProvider: DynamicModule = TypeOrmModule.forRootAsync({
  inject: [ConfigService],
  useFactory: buildDataSourceOptions
})

export function buildDataSourceOptions(configService: ConfigService): DataSourceOptions {
    return {
      type: 'postgres',
      host: config.get('DATABASE_HOST'),
      username: config.get('DATABASE_USERNAME'),
      password: config.get('DATABASE_PASSWORD'),
      port: config.get('DATABASE_PORT'),
      database: config.get('DATABASE_NAME'),
      autoLoadEntities: true,
      synchronize: false,
      migrations: [__dirname + '/../src/migrations/*{.ts,.js}'],
    };
}

og konfigurasjonsfilen for TypeORM CLI, i en separat fil (database.config.ts for eksempel)

import { ConfigModule, ConfigService } from '@nestjs/config';
import { DataSource } from 'typeorm';
import { buildDataSourceOptions } from './database.provider';

// This will load environment values.
ConfigModule.forRoot(/* Pass here the same options that you would pass when
calling this method from your root module */);

// This will be used by the cli
export default new DataSource(buildDataSourceOptions(new ConfigService()));

Derfor kan du kalle CLI-en på denne måten:

yarn run typeorm migration:generate ./src/migrations -d ./src/database/database.config.ts

Også støttes ikke alternativet autoLoadEntities av TypeORM CLI. Du kan erstatte dette alternativet med noe som dette entities: ['dist/**/*.entity{.ts,.js}']

Svar #2

I tider som dette, går vi tilbake til node ;-) Det er mye bedre å bruke dotenv. prøv dette Lag en databasemodul Legg til denne provideren database.provider.ts

import { registerAs } from "@nestjs/config";
import { config as dotenvConfig } from 'dotenv';
import { DataSource, DataSourceOptions } from "typeorm";

dotenvConfig({ path: '.env.dev' });

const config = {
    type: 'postgres',
    host: `${process.env.POSTGRES_HOST}`,
    port: `${process.env.POSTGRES_PORT}`,
    username: `${process.env.POSTGRES_USER}`,
    password: `${process.env.POSTGRES_PASSWORD}`,
    database: `${process.env.POSTGRES_DB}`,
    entities: ["dist/**/*.entity{.ts,.js}"],
    migrations: ["dist/migrations/*{.ts,.js}"],
    autoLoadEntities: true,
    synchronize: false,
}

export default registerAs('typeorm', () => config)
export const connectionSource = new DataSource(config as DataSourceOptions);

Og for databasen din modul

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import typeorm from './database.provider';


@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true, load: [typeorm]
    }), // Make ConfigModule global
    TypeOrmModule.forRootAsync({
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => (configService.get('typeorm'))
    }),
  ],
})
export class DatabaseModule { }

Legg dette til i package.json

"typeorm": "ts-node ./node_modules/typeorm/cli",
"migration:run": "npm run typeorm migration:run -- -d ./src/database/database.provider.ts",
"migration:generate": "npm run typeorm -- -d ./src/config/database.provider.ts migration:generate ./src/migrations/$npm_config_name",
"migration:create": "npm run typeorm -- migration:create ./src/migrations/$npm_config_name",
"migration:revert": "npm run typeorm -- -d ./src/database/database.provider.ts migration:revert"