TypeORM:在运行时动态设置EntityManager(或存储库)的数据库架构吗?

问题描述 投票:9回答:2

情况:

对于我们的SaaS API,我们使用schema-based multitenancy,这意味着每个客户(〜租户)在同一个(postgres)数据库中都有自己的单独的schema,而不会干扰其他客户。每个模式都包含相同的基础实体模型。

每次有新客户注册到系统时,都会在数据库中自动创建一个新的隔离模式。这意味着,该架构是在运行时创建的,并且事先未知。客户的架构是根据客户的域命名的。

对于到达我们API的每个请求,我们从JWT中提取用户的租约从属关系,并确定要使用哪个db模式来为此租户执行请求的db-operation。

问题

[通过TypeORM与(postgres)数据库建立连接后(例如,使用createConnection),为数据库操作设置模式的唯一机会是求助于createQueryBuilder

const orders = await this.entityManager
  .createQueryBuilder()
  .select()
  .from(`${tenantId}.orders`, 'order') // <--- setting schema-prefix here
  .where("order.priority = 4")
  .getMany();

这意味着,由于使用QueryBuilder(或EntityManager API)时似乎无法设置架构,因此我们被迫使用Repository API

但是,我们希望/需要使用这些API,因为它们更容易编写,需要更少的代码并且也更少出错,因为它们不依赖于使用基于字符串的语法“手动”编写查询。

问题

对于TypeORM,在使用EntityManager或存储库时是否可以通过某种方式设置db模式?

这样的事情?

// set schema when instantiating manager
const manager = connection.createEntityManager({ schema: tenantDomain });

// should find all matching "order" entities within schema
const orders = manager.find(Order, { priority: 4 })

// should find a matching "item" entity within schema using same manager
const item = manager.findOne(Item, { id: 321 })

注意:

  • db-schema需要以请求范围的方式设置,以避免为其他请求(可能属于其他客户)设置模式。不能为整个连接设置模式。
  • 我们知道,可以创建一个全新的连接并设置该连接的架构,但是我们想重用现有的连接。因此,简单地创建一个新连接来设置模式不是一个选择。
postgresql orm multi-tenant nestjs typeorm
2个回答
3
投票
回答我自己的问题:

目前,如果不创建新连接,就无法在运行时使用不同的架构实例化TypeORM repositories

因此,对于基于模式的多租户,开发人员只剩下两个选项:

    设置新的连接以在运行时与同一数据库中的不同架构连接。例如。参见NestJS Request Scoped Multitenancy for Multiple Databases。但是,绝对应该努力重用连接,并且要注意connection limits
  1. 放弃使用RepositoryApi并恢复为使用createQueryBuilder(或通过query()执行SQL查询的想法。
  • 为了进一步研究,这是一些TypeORM GitHub问题,这些问题跟踪在运行时更改现有连接或存储库的模式的想法(类似于OP中的要求:]

  • P.S。如果TypeORM决定支持OP中讨论的想法,我将尝试更新此答案。
  • 由于注释对我不起作用,因此来自NestJS文档的提示:

    https://docs.nestjs.com/techniques/database#async-configuration

    我不是在使用NestJS,而是在阅读文档以决定是否适合我们。我们有一个应用程序,其中只有一些模块的每个租户具有多租户架构,因此对我来说也可以使用TypeOrmModule.forRootAsync(dynamicCreatedDbConfig)

    如果您有拦截器或中间件,可以在...之前准备dynamicCreatedDbConfig数据,则可能会对您有所帮助。


    -2
    投票
    由于注释对我不起作用,因此来自NestJS文档的提示:
    © www.soinside.com 2019 - 2024. All rights reserved.