我正在寻找其他试图使用数据库级隔离构建多租户Django应用程序的工作代码和 idea .

Update/Solution:我在一个新的开源项目中结束了这个问题的解决:参见django-db-multitenant

目标

我的目标是根据请求主机名或请求路径(例如,foo.example.com/将Django连接设置为使用数据库foo,bar.example.com/使用数据库bar),在请求进入单个应用程序服务器(WSGI前端,如Gunicorn)时对其进行多路复用.

先例

我知道Django有几个现有的多租户解决方案:

  1. django-tenant-schemas:这非常接近我想要的:您以最高优先级安装它的中间件,然后它向数据库发送一个SET search_path命令.不幸的是,它是Postgres特有的,我只能使用MySQL.
  2. django-simple-multitenant:这里的策略是向所有模型添加一个"租户"外键,并调整所有应用程序业务逻辑以关闭该外键.基本上,每一行的索引都是(id, tenant_id),而不是(id).我try 过这种方法,但不喜欢这种方法,原因有很多:它使应用程序更加复杂,可能导致难以发现的错误,并且不提供数据库级别的隔离.
  3. 每个租户一个{应用程序服务器,具有适当数据库的Django设置文件}.也就是穷人的多租户(实际上是富人的,考虑到它所涉及的资源).我不想 for each 租户启动新的应用程序服务器,为了实现可伸缩性,我希望任何应用程序服务器都能够为任何客户端分派请求.

idea

到目前为止,我最好的 idea 是执行类似于django-tenant-schemas的操作:在第一个中间件中,抓取django.db.connection并处理数据库 Select ,而不是模式.我还没有完全考虑过这对于池式/持久性连接意味着什么

我追求的另一个死胡同是特定于租户的表前缀:撇开我需要它们是动态的不谈,即使是全局表前缀也不容易在Django中实现(参见rejected ticket 5000等).

最后,Django multiple database support允许您定义多个命名数据库,并根据实例类型和读/写模式在它们之间进行多路复用.没有帮助,因为没有基于每个请求 Select 数据库的设施.

问题

有人做过类似的事情吗?如果是,你是如何实施的?

推荐答案

作为记录,我 Select 实现我第一个 idea 的变体:在早期请求中间件中发出USE <dbname>.我还以同样的方式设置了缓存前缀.

我在一个小型生产站点上使用它,根据请求的主机从Redis数据库中查找租户名称.到目前为止,我对结果相当满意.

我已经把它变成了一个(希望可以恢复)github项目:https://github.com/mik3y/django-db-multitenant

Django相关问答推荐

Django:无法分配必须是实例(&Q;X),不想获取对象(&Q;)

POST_SAVE接缝有错误

Django:我的上下文变量不能用于重复的for循环

Django rest framework, AttributeError: 'str' object has no attribute 'data' 无法使用表单上传图片

为什么 timezone.now 在作为默认值应用于 Django 中的 DateField 时显示future 日期

有谁知道是否可以将您的 Django Heroku 应用程序放到 App Store/Google Play 上?

如何重命名标准 django-registration 模板的名称

如何将 select_related 应用于 Django 中的 m2m 关系的对象?

如何计算 Django 模型中特定对象的数量?

如何将 ManyToManyField 与另一个 ManyToManyField 进行比较

Django JSONField 过滤

在 django 模板中遇到 user.is_authenticated 问题

base.html 中的 Django 变量

related_name 参数在 Django 模型中没有按预期工作?

Django JavaScript 文件

如何使用基于类的视图处理表单(通过 get 或 post)?

在 Django 中舍入小数点

Django:何时使用 QuerySet 无

Jinja2中的多级模板继承?

Django - 安装 mysqlclient 错误:需要 mysqlclient 1.3.13 或更高版本;你有 0.9.3