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

NestJS启动调用main方法时出现TypeORM Driver not Connected错误

问题:启动时调用数据库操作报错“Driver not Connected”,控制器调用正常

我正在使用NestJS及其集成的TypeORM框架开发程序,依赖版本如下:

"dependencies": {
    "@nestjs/axios": "^3.0.1",
    "@nestjs/common": "^10.0.0",
    "@nestjs/config": "^3.1.1",
    "@nestjs/core": "^10.0.0",
    "@nestjs/platform-express": "^10.2.9",
    "@nestjs/schedule": "^4.0.0",
    "@nestjs/typeorm": "^10.0.0",
    "typeorm": "^0.3.9",
    "typeorm-extension": "^2.1.9"
}

主模块app.module.ts声明如下:

@Module({
    imports: [
        ScheduleModule.forRoot(),
        ConfigModule.forRoot({
            envFilePath: [ '.env.local' ],
            isGlobal: true,
            validationSchema: CoreJoi.object({
                DB_DATABASE: CoreJoi.string().required(),
                DB_HOST: CoreJoi.string().required(),
                DB_PASSWORD: CoreJoi.string().required(),
                DB_PORT: CoreJoi.number().required().default(5432),
                DB_SYNCHRONIZE: CoreJoi.boolean().default(false),
                DB_USERNAME: CoreJoi.string().required(),
            }),
        }),
        DatabaseModule,
        HttpModule
     ],
     providers: [AppService],
     controllers: [AppController],
})
export class AppModule {}

database.module.ts中通过异步函数从Secret Manager获取凭据初始化数据源:

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      imports: [ ConfigModule ],
      inject: [ ConfigService ],
      useFactory: (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get<string>('DB_HOST'),
        port: configService.get<number>('DB_PORT'),
        username: configService.get<string>('DB_USERNAME'),
        password: async () => {
          const secretManagerService = new SecretManagerServiceClient();

          const [accessResponse] = await secretManagerService.accessSecretVersion({
            name: configService.get<string>('DB_PASSWORD'),
          });

          return accessResponse.payload.data.toString();
        },
        database: configService.get<string>('DB_DATABASE'),
        synchronize: configService.get<boolean>('DB_SYNCHRONIZE'),
        autoLoadEntities: true,
      }),
    }),
    TypeOrmModule.forFeature([ /* my entities */ ]),
  ],
  providers: [ DatabaseService ],
  exports: [ DatabaseService ],
})
export class DatabaseModule {}

启动服务器时的main.ts代码如下:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  const appService = app.get(AppService);

  await appService.process();

  await app.close();
}
bootstrap();

启动后在需要使用数据库的环节出现以下错误:

throw new TypeORMError("Driver not Connected")
              ^
TypeORMError: Driver not Connected
    at PostgresQueryRunner.connect (...)
    at PostgresQueryRunner.query (...)

但如果通过暴露控制器接口调用appService.process(),例如:

@Post()
launchProcessing(): Promise<void> {
    return this.appService.process();
}

一切运行正常。请问如何解决该问题?我的配置是否存在问题?


解决方案

问题根源

  1. 密码获取逻辑错误:你在TypeORM配置的password字段中传入了一个异步函数,但TypeORM的配置解析不会自动处理这个异步函数的返回值,导致数据库初始化时密码未正确获取,连接无法建立。
  2. 连接未就绪就执行操作:await app.listen(3000)仅表示NestJS应用启动完成,但TypeORM的数据库连接可能还在异步初始化中,此时直接调用数据库操作会触发未连接错误。而控制器调用时,应用已完全初始化,连接已建立,所以正常运行。

修复步骤

1. 修正数据库密码获取逻辑

将获取Secret Manager密码的异步逻辑移到useFactory函数内部(useFactory本身支持异步),确保返回配置对象前已拿到有效密码:

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      imports: [ ConfigModule ],
      inject: [ ConfigService ],
      // 将useFactory改为异步函数
      useFactory: async (configService: ConfigService) => {
        const secretManagerService = new SecretManagerServiceClient();
        // 先获取密码
        const [accessResponse] = await secretManagerService.accessSecretVersion({
          name: configService.get<string>('DB_PASSWORD'),
        });
        const dbPassword = accessResponse.payload.data.toString();

        // 返回完整的数据库配置
        return {
          type: 'postgres',
          host: configService.get<string>('DB_HOST'),
          port: configService.get<number>('DB_PORT'),
          username: configService.get<string>('DB_USERNAME'),
          password: dbPassword,
          database: configService.get<string>('DB_DATABASE'),
          synchronize: configService.get<boolean>('DB_SYNCHRONIZE'),
          autoLoadEntities: true,
        };
      },
    }),
    TypeOrmModule.forFeature([ /* my entities */ ]),
  ],
  providers: [ DatabaseService ],
  exports: [ DatabaseService ],
})
export class DatabaseModule {}

2. 确保数据库连接就绪后再执行操作

在main.ts中手动等待TypeORM的DataSource初始化完成,再调用业务逻辑:

import { DataSource } from 'typeorm';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  // 等待数据库连接初始化完成
  const dataSource = app.get(DataSource);
  await dataSource.initialize();

  const appService = app.get(AppService);
  await appService.process();

  await app.close();
}
bootstrap();

通过以上两步,就能保证启动时数据库连接已正确建立,执行appService.process()时不会出现未连接错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:07:43