postgresql - 如何为多租户 Web 应用程序动态创建模式/表
问题描述
问题
我正在构建一个网络应用程序,每个用户都需要隔离数据(由于机密性),但具有完全相同的数据结构/表。
环顾四周我觉得这个概念叫多租户?似乎一个好的解决方案是每个租户 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 似乎会自动公开创建表,我想避免这种情况。
奖金问题
创建架构后,如果我需要将表添加到所有架构中 - 管理它的最佳方法是什么?烧瓶迁移本身可以处理吗?
谢谢!
解决方案
如果将来有人看到这一点,则此解决方案似乎可以广泛使用,但是我最近遇到了一个问题。
这条线
table.__table__.schema = user.name
似乎会产生一些奇怪的行为,其中 user.name 的值似乎在应用程序的顺序区域中持续存在,因此如果您切换用户,则会错误地查询前一个用户的表。
我不完全确定为什么会发生这种情况,并且仍在研究如何解决它。
推荐阅读
- dialogflow-es - Dialogflow 培训对话
- asp.net-core - 如何从外部 dll 加载标签助手
- django - Django Inline Formset Clean 方法不会在模板中引发验证错误?
- django - 当我使用 django 生成 pdf 时,我不能写格鲁吉亚语。我的代码除了格鲁吉亚字母外还写了黑色方块
- gis - 如何在 Windows 的 grads 中打开 grib 数据集?
- excel - 删除不同扩展名文件夹中的空 Excel 文件
- reactjs - React native 的这个组件有什么问题?我想在按钮按下时改变方块的颜色
- sql - 将数组作为 json 格式的密钥对传递给函数 pgsql
- javascript - 在 React 中渲染 Pokemon 双类型弱点/抗性
- c++ - 为什么我的代码不接受字母作为用户输入