Nest 无法将 DataSource 解析为依赖项

Bok*_*ero 14 node.js typescript typeorm nestjs

我在 NestJS 中遇到了依赖关系问题。在启动我的 NestJS 应用程序时,编译器向我抛出以下错误:

[Nest] 16004  - 09.04.2022, 16:14:46   ERROR [ExceptionHandler] Nest can't resolve dependencies of the AccountService (MailingService, ?). Please make sure that the argument DataSource at index [1] is available in the AccountModule context.
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我我做错了什么吗?

这是我的模块:

@Module({
  imports: [],
  providers: [AccountService, MailingService],
  controllers: [AccountController],
  exports: []
})
export class AccountModule {}

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      useClass: TypeOrmConfigService,
    }),
  ],
})
export class DatabaseModule {}

@Module({
  imports: [
    DatabaseModule,
    ConfigModule.forRoot({
      envFilePath: '.env',
    }),
    ScheduleModule.forRoot(),
    AccountModule,
    AuthModule,
    MailingModule],
  controllers: [AppController],
  providers: [],
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助!

附言。DataSource是 TypeORM 中用于查询的类,之前它是Connection类

小智 6

正确的方法是提供一个自定义数据源工厂,如官方文档所述。

 TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      // Use useFactory, useClass, or useExisting
      // to configure the DataSourceOptions.
      useFactory: (configService: ConfigService) => ({
        type: 'mysql',
        host: configService.get('HOST'),
        port: +configService.get('PORT'),
        username: configService.get('USERNAME'),
        password: configService.get('PASSWORD'),
        database: configService.get('DATABASE'),
        entities: [],
        synchronize: true,
      }),
      // dataSource receives the configured DataSourceOptions
      // and returns a Promise<DataSource>.
      dataSourceFactory: async (options) => {
        const dataSource = await new DataSource(options).initialize();
        return dataSource;
      },
    });
Run Code Online (Sandbox Code Playgroud)

  • 我有一个问题,typeorm cli 需要一个 dataSource 实例,如果我们使用这个示例,我该如何使用 typeorm cli?`"typeorm": "typeorm-ts-node-commonjs --dataSource app.module.ts"`??? (2认同)

Jul*_*lez 6

文档对此不是很清楚,但我发现你可以使用包@InjectDataSource()中的装饰器@nest/typeorm。

例子:

import { DataSource } from 'typeorm';
import { InjectDataSource } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(
    @InjectDataSource()
    private dataSource: DataSource
  ) {}
}
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用。我在 App.module 中使用 TypeOrmModule.forRoot 初始化数据源。我尝试在另一个模块中导入数据源...... (3认同)

Jul*_*ano 5

我创建了自己的 TypeOrmModule:

import { Global, Module } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { typeOrmConnectionDataSource } from './typeorm-datasource';

@Global()
@Module({
  imports: [],
  providers: [
    {
      provide: DataSource,
      useFactory: async () => {
        await typeOrmConnectionDataSource.initialize();
        return typeOrmConnectionDataSource;
      },
    },
  ],
  exports: [DataSource],
})
export class TypeOrmModule {}
Run Code Online (Sandbox Code Playgroud)

这是“./typeorm-datasource”(但替换为您的配置):

import { DataSource } from "typeorm"

export const typeOrmConnectionDataSource = new DataSource({
  name: "default",
  type: "postgres",
  host: "localhost",
  port: 15432,
  username: "postgres",
  password: "postgres",
  database: "postgres",
  synchronize: false,
  schema: "my-schema",
  migrationsRun: false,
  entities: [`${__dirname}/**/**.entity{.ts,.js}`],
  migrations: [`${__dirname}/migrations/**/*{.ts,.js}`],
});
Run Code Online (Sandbox Code Playgroud)


小智 5

第一步我们必须创建数据库提供程序。

数据库.providers.ts

import { DataSource } from 'typeorm';

export const databaseProviders = [
    {
        provide: DataSource,
        useFactory: async () => {
            // You can inject config service to provide dynamic DataSourceOptions
            const dataSource = new DataSource({
                type: 'mysql',
                host: 'localhost',
                port: 3306,
                username: 'root',
                password: 'root',
                database: 'test',
                entities: [
                    __dirname + '/../**/*.entity{.ts,.js}',
                ],
                synchronize: true,
            });
            try {
                if (!dataSource.isInitialized) {
                    await dataSource.initialize();
                }
            } catch (error) {
                console.error(error?.message);
            }
            return dataSource;
        }
    }
];

Run Code Online (Sandbox Code Playgroud)

现在我们可以在 DatabaseModule 中导入/导出我们的数据库提供程序。

数据库模块.ts

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
    providers: [...databaseProviders],
    exports: [...databaseProviders],
})
export class DatabaseModule {}

Run Code Online (Sandbox Code Playgroud)

现在,我们可以将 DataSouce 依赖项注入到任何功能模块中。IEphoto.module.ts

注意:不要忘记导入到DatabaseModule里面PhotoModule。


Bok*_*ero 1

我解决了它,问题出在DataSource课堂上,文档告诉我们:DataSource is a pre-defined connection configuration to a specific database. You can have multiple data sources connected (with multiple connections in it), connected to multiple databases in your application.。因此,我们不能使用此类作为提供者来查询我们的实体。

在早期版本中,TypeORM我们可以使用Connection类,但现在最好的选择是使用EntityManagerinstaed ofDataSource或 deprecatedConnection

  • 你有实体管理器的例子吗? (4认同)
  • 如果此解决方案适合您,请以代码片段的形式提供示例 (2认同)