postgresql - 如何处理为 Multi-Tenancy Web 应用程序动态创建模式/表

标签 postgresql flask sqlalchemy flask-sqlalchemy multi-tenant

问题

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

环顾四周我认为这个概念叫做 Multi-Tenancy ?似乎一个好的解决方案是每个租户 1 个模式。

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

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

然而,这似乎假设模式和表已经创建。

我不确定我将拥有多少个租户,所以我需要在创建用户帐户时即时创建模式和其中的表。

解决方案

我的想法有点像 hack,这就是为什么我在这里发帖看看是否有更好的解决方案。

我正在使用动态创建模式

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 似乎会自动公开创建表,我想避免这种情况。

奖金问题

模式创建后,如果我需要向所有模式添加表 - 管理它的最佳方法是什么? flask-migrations 本身会处理吗?

谢谢!

最佳答案

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

这一行

table.__table__.schema = user.name

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

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

关于postgresql - 如何处理为 Multi-Tenancy Web 应用程序动态创建模式/表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64587003/

相关文章:

python - 如何将参数传递给 after_request?

python - 在 python 线程中使用 flask session

python - 无法在 mongoengine 上呈现列表字段 model_form

python - SQLAlchemy MySQL 重复键更新

python - 几何字段的 AdminModelConvertor (LON/LAT)

sql - 合并、组合、合并行

java - PostGIS 函数不能在 java 中使用 hibernate ?

java - 如何在 postgres - Hibernate 中设置锁定超时

python - 使用获取相同值的只读列覆盖只读属性

postgresql - 如何从 Postgresql 数据库获取数据到 Angular 网站?