在TypeORMModule.forRootAsync中使用connectionName时NestJS抛出依赖异常
NestJS + TypeORM 多数据源配置依赖异常排查
问题
在TypeORM.forRootAsync中添加name: 'psql'属性后,NestJS应用启动抛出依赖解析异常,提示AccountRepository无法获取DataSource。
相关代码
AppModule
@Module({ imports: [ UsersModule, TypeOrmModule.forRootAsync({ name: 'psql', // 添加此行后报错 useFactory: () => { return { type: 'postgres', host: process.env.POSTGRES_DATABASE_HOST, port: parseInt(process.env.POSTGRES_DATABASE_PORT), username: process.env.POSTGRES_DATABASE_USERNAME, password: process.env.POSTGRES_DATABASE_PASSWORD, database: process.env.POSTGRES_DATABASE_NAME, logging: false, autoLoadEntities: true, synchronize: false, }; }, }), GroupsModule, EventsModule, AccountsModule, ConfigModule.forRoot({ isGlobal: true }), AuthModule, IntegrationsModule, MailModule, ], controllers: [AppController], providers: [AppService], exports: [TypeOrmModule], }) export class AppModule {}
AccountsModule
@Module({ imports: [ TypeOrmModule.forFeature([Account, Project, ApiKey, Operator, ProjectRole, Session], 'psql'), CqrsModule, ConfigModule, MailModule, BullModule.registerQueue({ name: 'projects', }), JwtModule.register({ secret: process.env.JWT_SECRET, signOptions: { expiresIn: '30d' }, }), ], controllers: [AccountsController, ApikeysController, ProjectsController, OperatorsController], exports: [ApikeysService, ApiKeyRepository, AccountRepository, ProjectRepository, OperatorsService], providers: [...], }) export class AccountsModule {}
AccountRepository
import { AggregateRoot, EventBus } from '@nestjs/cqrs'; import { v4 as uuidv4 } from 'uuid'; import { HttpException, HttpStatus, Logger } from '@nestjs/common'; import { Account } from '../entities/account.entity'; import { AccountCreatedEvent } from '../events/account-created.event'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; export class AccountRepository extends AggregateRoot { private readonly logger = new Logger('Account Repository'); constructor(private eventBus: EventBus, @InjectRepository(Account) private readonly accountRepository: Repository<Account>) { super(); } async create(name: string, slug: string): Promise<Account> { this.logger.debug(`Checking if account exists`); if (await this.get({ slug })) { throw new HttpException('Account slug already exists', HttpStatus.BAD_REQUEST); } const id = uuidv4(); const createdAt = new Date(); const account: Account = this.accountRepository.create({ id, name, slug, createdAt }); await this.accountRepository.save(account); this.logger.debug(`Posting AccountCreatedEvent`); this.eventBus.publish(new AccountCreatedEvent(id)); return { id, slug, name, createdAt }; } }
错误信息
Nest can't resolve dependencies of the AccountRepository (?). Please make sure that the argument DataSource at index [0] is available in the TypeOrmModule context. Potential solutions: - If DataSource is a provider, is it part of the current TypeOrmModule? - If DataSource is exported from a separate @Module, is that module imported within TypeOrmModule? @Module({ imports: [ /* the Module containing DataSource */ ] })
解决方案
1. 注入Repository时指定数据源名称
配置命名数据源后,@InjectRepository必须明确指定数据源名称,否则Nest会默认查找未命名的默认数据源(当前仅配置了psql命名数据源)。修改AccountRepository的构造函数:
constructor( private eventBus: EventBus, @InjectRepository(Account, 'psql') // 添加第二个参数指定数据源名称 private readonly accountRepository: Repository<Account> ) { super(); }
2. 调整ConfigModule加载顺序
AppModule中ConfigModule.forRoot在TypeOrmModule之后加载,会导致TypeOrm的useFactory执行时环境变量未初始化,可能引发配置读取错误。将ConfigModule.forRoot移到imports数组最前面:
@Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), // 移到最顶部 UsersModule, TypeOrmModule.forRootAsync({ name: 'psql', useFactory: () => { // ... 原有配置 }, }), // ... 其他模块 ], // ... 其他配置 }) export class AppModule {}
3. 统一所有关联Repository的数据源配置
如果其他自定义Repository(如ApiKeyRepository、ProjectRepository等)也注入了实体Repository,同样需要在@InjectRepository中添加'psql'参数,确保所有操作都指向同一命名数据源。
内容的提问来源于stack exchange,提问作者Luis Novo
相关产品推荐
相关产品推荐

