使用共享架构的 SQLAlchemy 中基于行/列的多租户

kon*_*tin 6 sqlalchemy multi-tenant flask-sqlalchemy

我想使用 Flask + SQLAlchemy 构建一个多租户应用程序。官方 SQLAlchemy 文档建议,要使用多租户,表应该分布在每个租户的 1 个方案上,并在引擎级别处理不同的租户。

维护多个方案对我来说似乎有点臃肿,我想知道如果设计正确,以下方法对所有租户使用相同的表是否可行,如果不是,为什么不:

  • 那些包含租户所有记录的表有一个不可为空的列tenant_id,指示哪个租户“拥有”该行。
  • Create/Update 语句(INSERTUPDATE)自动将此列的值设置为当前租户。
  • 读取/删除查询(SELECTDELETE)查询会自动WHERE tenant_id=:current tenant向 SQL添加子句/过滤器。
  • 的值tenant_id可以派生自 JSON Web 令牌。
  • 这个自动设置的值/where 子句可以在后台管理,例如通过像这个答案中的自定义会话或使用预提交钩子。

我几乎找不到关于这种方法的任何信息(除了这个名为MultiAlchemy 的软件包,它似乎与我的描述类似,但已存档且 7 年未更新)。我的直觉说,这是有原因的。

tl;dr:为什么不在 SQLAlchemy 中使用共享方案进行多租户?

inf*_*fra 0

这是两种不同的多租户方法:

  • 每个租户 1-scheme-per-tenant 看起来像这样public.companies, company_a.users, company_a.posts, company_b.users, company_b.posts, ...,并且在这些表中不会引用实际租户(公司)
    • 它非常适合在多个数据库之间分配数据
    • 当添加/删除租户是非常罕见的事件时,它效果更好,因为它是一个有点复杂的过程(创建新模式等)
    • 在模式/数据库管理方面需要额外的努力
    • 跨租户请求难以实现
  • 共享模式看起来像一组固定的表public.companies, public.users, public.posts,并且表将包含对实际租户的引用(例如company_id)
    • 添加/删除租户是一个非常简单的过程
    • 单一模式需要更少的管理
    • 跨租户请求很简单
    • 这种方法很难在数据库之间扩展或分布

我想说这主要取决于租户数量和数据大小。有几个租户,但有大量数据,那么第一种方法肯定更好。租户数量是动态的,那么第二种方法更好。

我之前没有见过第二种方法的一般实现,比如MultiAlchemy,我个人会尝试一下。