我如何使用 TypeOrmModule.forRootAsync 作为数据源生成迁移?

问题描述 投票:0回答:2

尝试将迁移集成到nest.js项目中,我从typeorm运行了migration:create命令,没有问题,但是当我尝试使用migration:generate生成迁移时,如下所示:

yarn run typeorm migration:generate ./src/migrations -d ./src/database/database.provider.ts
./src/migrations 是我想要迁移的文件夹,./src/database/database.provider.ts 是我的数据源,稍后我将向您展示,重点是我收到以下错误: `

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.

这是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;
  }
})

这是我的数据库模块:

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

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

我尝试使用旧的 typeorm 命令,例如:

yarn run typeorm migration:generate -n newMigration 
。 我已经检查了文档一百遍了,他们没有告诉你如何使用 typeormmoduleconfig 作为数据源来生成迁移,我正在考虑创建一个 ormconfig.json 但我不喜欢它,如果没有其他效果,我想我没有太多选择。

javascript typescript nestjs migration nestjs-typeorm
2个回答
0
投票

您提供给命令

database.provider.ts
的文件
yarn run typeorm migration:generate
导出 NestJS 动态模块,而不是 TypeORM CLI 可以使用的数据源。

但是,您可以在

database.provider.ts
中添加一个构建数据源选项的函数,然后在单独的文件中重用此函数来构建 CLI 所需的配置。

在您的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}'],
    };
}

以及 TypeORM cli 的配置文件,位于单独的文件中(例如

database.config.ts

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()));

因此,您可以这样调用 CLI :

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

此外,TypeORM CLI 不支持选项

autoLoadEntities
。您可以将此选项替换为类似的内容
entities: ['dist/**/*.entity{.ts,.js}']


0
投票

在这种情况下,我们会回到节点;-) 使用 dotenv 更好。 试试这个制作一个数据库模块 添加此提供程序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);

对于您的数据库模块

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 { }

将此添加到包 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"
© www.soinside.com 2019 - 2024. All rights reserved.