代码之家  ›  专栏  ›  技术社区  ›  Felix K.

TypeORM:在运行时为EntityManager或存储库动态设置数据库模式?

  •  0
  • Felix K.  · 技术社区  · 5 年前

    情况:

    schema-based multitenancy ,这意味着每个客户(~租户)都有自己的 schema

    每次向系统注册新客户时,都会在数据库中自动创建新的独立模式。这意味着,模式是在运行时创建的,而不是预先知道的。客户的模式是根据客户的域命名的。

    问题

    在通过 TypeORM 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

    像这样的?

    // 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 })
    

    笔记:

    • 需要以请求范围的方式设置数据库架构,以避免为可能属于其他客户的其他请求设置架构。为整个连接设置架构不是一个选项。
    • 我们知道可以创建一个全新的连接并为此连接设置模式,但是我们希望重用现有连接。因此,简单地创建一个新连接来设置模式不是一个选项。
    0 回复  |  直到 5 年前
        1
  •  2
  •   Felix K.    4 年前

    回答我自己的问题:

    目前没有方法实例化 TypeORM repositories 在运行时使用不同的模式,而不创建新连接。

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

    1. NestJS Request Scoped Multitenancy for Multiple Databases . 但是,一个人必须努力重用连接,并意识到 connection limits .
    2. RepositoryApi 并恢复使用 createQueryBuilder (或通过 query() ).

    为了进一步研究,这里有一些TypeORM GitHub问题,它们跟踪在运行时更改现有连接或存储库的模式的想法(类似于OP中的请求):

    P、 如果TypeORM决定支持OP中讨论的想法,我会尝试更新这个答案。

        2
  •  -2
  •   weihs.th    5 年前

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

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

    如果您有一个拦截器或中间件,它可以在。。。