简体   繁体   English

Nestjs:在没有类依赖注入的情况下使用 TypeOrm 数据源

[英]Nestjs: Use TypeOrm datasource without class dependency injection

I have an unusual request.我有一个不寻常的请求。 We are implementing nestjs into our existing express codebase.我们正在将 nestjs 实施到我们现有的 express 代码库中。 Before, we were using Typeorm 0.2 and upgraded to 0.3.之前,我们使用的是 Typeorm 0.2,升级到 0.3。 We are using functions and not classes, therefore, without huge refactoring, we can't use datasource dependency injection.我们使用的是函数而不是类,因此,如果不进行大量重构,我们将无法使用数据源依赖注入。 The goal is to use the datasource without the nestjs dependecy injection.目标是在没有 nestjs 依赖注入的情况下使用数据源。

We used to build transactions this way:我们曾经以这种方式建立交易:

import { getManager } from 'typeorm';
    
return getManager().transaction((manager) => {
  // do something
});

Now, with TypeOrm 0.3, getManager is deprecated.现在,在 TypeOrm 0.3 中,不推荐使用getManager The code is compiling and all requests that don't contain the getManager function are working.代码正在编译,所有不包含getManager函数的请求都在工作。 When the function containing it is called, I get the following error:当调用包含它的函数时,出现以下错误:

ConnectionNotFoundError: Connection "default" was not found.

I tried to work with the datasource directly, but the infamous error of "metadata not found" is coming up and the code does not even compile.我试图直接使用数据源,但出现了臭名昭著的“未找到元数据”错误,代码甚至无法编译。

import { getManager } from 'typeorm';

return AppDataSource.transaction((manager) => {
  // do something
});
Entity metadata for BuyerIndustry#companies was not found. Check if you specified a correct entity object and if it's connected in the connection options.

This is, how we set up the datasource and imported it in the AppModule :这就是我们如何设置数据源并将其导入AppModule

import { ConfigService } from '@nestjs/config';
import { DataSource } from 'typeorm';
import { repositories } from './repositories';

const configService = new ConfigService();

export const AppDataSource = new DataSource({
    type: 'postgres',
    host: configService.get('POSTGRES_HOST'),
    port: configService.get('POSTGRES_PORT'),
    username: configService.get('POSTGRES_USER'),
    password: configService.get('POSTGRES_PASSWORD'),
    database: configService.get('POSTGRES_DB'),
    migrations: [__dirname + '/src/database/migrations/*{.ts,.js}'],
    entities: repositories,
    synchronize: false,
});
// repositories.ts
export const repositories = [
    BuyerIndustry,
    Company,
    // and all other entities in the application
];
// typeorm.module.ts
import { Global, Module } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { AppDataSource } from './datasource';

@Global()
@Module({
    imports: [],
    providers: [
        {
            provide: DataSource,
            useFactory: async () => {
                await AppDataSource.initialize();

                return AppDataSource;
            },
        },
    ],
    exports: [DataSource],
})
export class CustomTypeOrmModule {}
// main.module.ts

@Module({
    imports: [
        CustomTypeOrmModule,
        // other modules
    ]
export class AppModule {
    constructor(private dataSource: DataSource) {}
}

Again, I am 100% certain that I imported ALL entities in the repositories.ts .同样,我 100% 确定我在repositories.ts中导入了所有实体。 Any idea, how we can use the DataSource directly in functions, without needing a class with the datasource injected?任何想法,我们如何可以直接在函数中使用DataSource ,而不需要注入数据源的类? Any help would be appreciated, thanks!任何帮助将不胜感激,谢谢!

First make sure AppDataSource is initialized.首先确保 AppDataSource 已初始化。 you can do this in the main.ts file您可以在main.ts文件中执行此操作

// main.ts
import {AppDataSource } from "..." // Your datasource file

 if (!AppDataSource.isInitialized) {
    await AppDataSource.initialize();
  }

then call it in any service like so然后像这样在任何服务中调用它


const someRepo = AppDataSource.getRepository(SomeRepoEntity);

someRepo.findOne({where:{id:someId}})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM