django - 使用单独模式的 Django 和 Postgresql 分层 Multi-Tenancy 架构

标签 django postgresql database-design architecture multi-tenant

我有一个 Django 应用程序有客户端和链接到这些客户端的多个用户,我想将系统迁移到分层 Multi-Tenancy 架构。

分层部分

客户端可以递归地包含其他客户端。例如,客户端 A 包括 客户端 B客户端 C。如果用户 Client A 登录系统,用户将看到 Client BClient C 的数据。如果 Client B 的用户登录系统,用户将只能看到 Client B 的数据。

Multi-Tenancy 部分

我想将所有客户的数据存储在单独的架构中。但是有些数据与客户无关,所以我想将这些数据存储在“公共(public)”架构中。

当我研究 Building Multi Tenant Applications with Django ,我看到了这部分:

def set_tenant_schema_for_request(request):
    schema = tenant_schema_from_request(request)
    with connection.cursor() as cursor:
        cursor.execute(f"SET search_path to {schema}")

但是,要应用我上面提到的分层示例,我必须同时访问多个模式。我可以这样做吗?还有其他方法可以实现我的架构吗?

最佳答案

您可以在 PostgreSQL 搜索路径中列出多个模式。如果同一个表出现在多个模式中,则仅返回搜索路径中第一个模式中的行。不同模式中的表中的行不会自动组合。所以这可能不是你想要的。

您可以重新构建您的应用程序,以便每个查询都从不同模式的表中选择数据,然后使用联合子句将这些结果连接在一起。虽然这提供正确的结果,但应该清楚的是,以这种方式构建所有查询会使应用程序变得非常复杂,并且这也不是一个好的计划。

如果您希望能够同时查看来自多个客户端的数据,具有隔离架构的 Multi-Tenancy 架构并不是正确的选择。排除了备选方案后,我认为只剩下一种方法了。您必须对同一表中来自不同客户端的行使用共享模式 Multi-Tenancy 。

拥有共享模式意味着来自不同客户端的数据分离较少,但它提供了一种简单的方法来在需要时同时显示来自多个客户端的数据。通常的实现方法是在查询的 where 子句中添加术语,以确保只返回对登录用户可见的数据。

您可能会考虑的另一种可能性是在数据库中使用行级安全性。使用这种方法,每个客户端都将拥有自己的 Postgres 用户帐户,该帐户具有限制访问仅适用于他们的行的策略。这将确保正确安全性的一些责任从应用程序层推到了数据库层,这有利也有弊。一个好处是安全性只需在数据库中实现一次,而不是在应用程序的整个数据访问部分实现。一个可能的缺点是数据库要做的工作可能更多。

https://www.postgresql.org/docs/11/ddl-rowsecurity.html

关于django - 使用单独模式的 Django 和 Postgresql 分层 Multi-Tenancy 架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53206853/

相关文章:

python - 如何使用序列化器获取 django 中的所有 related_name 字段?

sql - 如何获取一列中具有最大值的行?

mysql - 国家数据库如何扩展?

python - 加载夹具时 Django 单元测试出错

python - 外键中所有字段的django values_list

mysql - 向查询优化器建议计划

java - 存储在 Heroku 上运行的基于 Java 的 REST 服务的图像

sql-server - 有关具有庞大数据集的数据库结构的建议

mysql - 管理文件/项目关系的最佳方式是什么?

python - 将 Django 用于非 http 请求