【问题标题】:How to handle creating schema/tables on the fly for a multi-tenant web app如何为多租户 Web 应用程序动态创建模式/表
【发布时间】:2020-10-29 07:55:33
【问题描述】:

问题

我正在构建一个网络应用程序,其中每个用户都需要有隔离的数据(由于机密性),但具有完全相同的数据结构/表。

环顾四周我觉得这个概念叫多租户?似乎一个好的解决方案是每个租户 1 个架构。

我认为sqlalchemy 1.1 对此实现了一些支持

session.connection(execution_options={
    "schema_translate_map": {"per_user": "account_one"}})

但这似乎假设架构和表已经创建。

我不确定我将拥有多少租户,因此我需要在创建用户帐户时动态创建架构和其中的表。

解决方案

我想出的东西有点像黑客,这就是为什么我在这里发帖看看是否有更好的解决方案。

我正在使用动态创建架构

if not engine.dialect.has_schema(engine, user.name):
   engine.execute(sqlalchemy.schema.CreateSchema(user.name))

然后直接在创建表格后使用

table = TableModel()
table.__table__.schema = user.name
table.__table__.create(db.session.bind)

将 TableModel 定义为

class TableModel(Base):

    __tablename__ = 'users'

    __table_args__ = {'schema': 'public'}

    id = db.Column(
        db.Integer,
        primary_key=True
    )

    ...

我不太清楚为什么要从 Base 继承 vs db.Model - db.Model 似乎会自动公开创建表,我想避免这种情况。

额外问题

创建架构后,如果我需要将表添加到所有架构中 - 管理它的最佳方法是什么?烧瓶迁移本身可以处理吗?

谢谢!

【问题讨论】:

  • 我现在也有类似的问题,我没有你那么先进,但是你可能会发现这两个链接很有帮助。第一篇文章描述了一种似乎与您的方法一致的方法。 medium.com/@hamza.senhajirhazi/… / 第二篇文章是对您的奖励问题的可能答案,并且与 Postgres 中的自动迁移有关,这里是在多个数据库而不是模式上:benchling.engineering/…
  • 我没有在中篇文章中描述如何动态创建表,他们使用 sql 编辑器创建表,尽管我不知道 before_request,这似乎会有所帮助。谢谢!
  • 一个问题...在租户模型中使用不同的模式很有用,它为不同的租户提供不同的功能。如果您说数据将完全相同,为什么不使用 RLS 代替呢?从概念上和操作上来说,这是一个更容易的过程。
  • @grommit 老实说,我不知道 RLS - 我会调查一下。感觉就像在同一张桌子上放东西会降低安全性?但我想如果正确实施,这不一定是正确的。

标签: postgresql flask sqlalchemy flask-sqlalchemy multi-tenant


【解决方案1】:

如果将来有人看到这个,这个解决方案似乎可以广泛使用,但是我最近遇到了一个问题。

这一行

table.__table__.schema = user.name

似乎会产生一些奇怪的行为,其中 user.name 的值似乎会持续存在于应用程序的订单区域中,因此如果您切换用户,则会错误地查询前一个用户的表。

我不完全确定为什么会发生这种情况,并且仍在研究如何解决它。

【讨论】:

    猜你喜欢
    • 2011-02-16
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 2020-05-08
    • 1970-01-01
    相关资源
    最近更新 更多