You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS中useFactory配置TypeORM时如何导出DataSource解决迁移报错

问题描述

基于NestJS框架开发应用,app.module.ts中通过useFactory编写TypeORM异步配置,全局安装TypeORM且迁移文件已生成到配置指定路径,执行迁移命令时提示dataSource未找到。

原有配置代码

import { ConfigModule, ConfigService } from '@nestjs/config';
import {
  TypeOrmModuleAsyncOptions,
  TypeOrmModuleOptions,
} from '@nestjs/typeorm';
import { DataSource } from 'typeorm';  

export const typeOrmAsyncConfig: TypeOrmModuleAsyncOptions = {
  imports: [ConfigModule],
  inject: [ConfigService],
  name: 'nameA',
  useFactory: (configService: ConfigService) => ({
    type: 'postgres',
    host: configService.get('DB_HOST'),
    port: parseInt(configService.get('DB_PORT') || '5432'),
    username: configService.get('DB_USER'),
    password: configService.get('DB_PASSWORD'),
    database: configService.get('DB_NAME'),
    entities: [__dirname + './../**/*.entity{.ts,.js}'],
    migrations: [__dirname + '/../database/migrations/*{.ts,.js}'],
    synchronize: false,
    cli: {
      entitiesDir: __dirname + './../**/*.entity{.ts,.js}',
    },
    ssl: configService.get('DB_SSL') === 'true',
  }),
};

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRootAsync(typeOrmAsyncConfig),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

执行迁移命令报错输出

执行typeorm migration:run返回如下结果:

Runs all pending migrations.

Options:
  -h, --help         Show help                                         [boolean]
  -d, --dataSource   Path to the file where your DataSource instance is defined.
                                                                      [required]
  -t, --transaction  Indicates if transaction should be used or not for
                     migration run. Enabled by default.     [default: "default"]
  -v, --version      Show version number                               [boolean]

Missing required argument: dataSource
报错原因

TypeORM 0.3及以上版本的CLI执行迁移时,不会加载NestJS的依赖注入容器,写在AppModule里的异步配置仅在NestJS应用启动时生效,CLI运行时无法读取到这些配置,必须显式传入一个可被直接加载的独立DataSource实例文件。

解决步骤
  • 第一步:创建独立的DataSource配置文件
    在项目中新建src/config/data-source.ts,手动加载环境变量,初始化并导出DataSource实例,配置字段和原有TypeORM配置保持一致:
    import { DataSource } from 'typeorm';
    import { config } from 'dotenv';
    
    // 加载.env文件环境变量,对齐NestJS ConfigModule的加载逻辑
    config();
    
    export const AppDataSource = new DataSource({
      type: 'postgres',
      host: process.env.DB_HOST,
      port: parseInt(process.env.DB_PORT || '5432'),
      username: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_NAME,
      entities: [__dirname + '/../**/*.entity{.ts,.js}'],
      migrations: [__dirname + '/../database/migrations/*{.ts,.js}'],
      synchronize: false,
      ssl: process.env.DB_SSL === 'true',
    });
    
  • 第二步:调整NestJS中的TypeORM配置,复用DataSource配置避免两边不一致
    修改app.module.ts中的typeOrmAsyncConfig,直接引用上面导出的DataSource配置项,单数据源场景建议移除name: 'nameA'配置避免多数据源冲突,多数据源场景则保证两边name值完全一致:
    import { AppDataSource } from './config/data-source';
    
    export const typeOrmAsyncConfig: TypeOrmModuleAsyncOptions = {
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        ...AppDataSource.options,
        // 有需要动态覆盖的配置可以在这里追加
      }),
    };
    
  • 第三步:执行迁移命令时显式传入DataSource文件路径
    不推荐直接使用全局安装的typeorm命令执行(无法识别TS语法、容易出现版本不匹配问题),推荐用项目本地依赖的typeorm配合ts-node执行:
    # 开发环境执行TS格式配置
    ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:run -d src/config/data-source.ts
    
    # 生产环境执行编译后的JS格式配置
    node ./node_modules/typeorm/cli.js migration:run -d dist/config/data-source.js
    

注意:如果项目配置了tsconfig路径别名,必须加上-r tsconfig-paths/register参数,否则会出现模块找不到的错误。

内容的提问来源于stack exchange,提问作者juztcode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:54:22