我正在寻找其他试图使用数据库级隔离构建多租户Django应用程序的工作代码和 idea .
Update/Solution:我在一个新的开源项目中结束了这个问题的解决:参见django-db-multitenant
目标
我的目标是根据请求主机名或请求路径(例如,foo.example.com/
将Django连接设置为使用数据库foo
,bar.example.com/
使用数据库bar
),在请求进入单个应用程序服务器(WSGI前端,如Gunicorn)时对其进行多路复用.
先例
我知道Django有几个现有的多租户解决方案:
-
django-tenant-schemas:这非常接近我想要的:您以最高优先级安装它的中间件,然后它向数据库发送一个
SET search_path
命令.不幸的是,它是Postgres特有的,我只能使用MySQL. -
django-simple-multitenant:这里的策略是向所有模型添加一个"租户"外键,并调整所有应用程序业务逻辑以关闭该外键.基本上,每一行的索引都是
(id, tenant_id)
,而不是(id)
.我try 过这种方法,但不喜欢这种方法,原因有很多:它使应用程序更加复杂,可能导致难以发现的错误,并且不提供数据库级别的隔离. - 每个租户一个{应用程序服务器,具有适当数据库的Django设置文件}.也就是穷人的多租户(实际上是富人的,考虑到它所涉及的资源).我不想 for each 租户启动新的应用程序服务器,为了实现可伸缩性,我希望任何应用程序服务器都能够为任何客户端分派请求.
idea
到目前为止,我最好的 idea 是执行类似于django-tenant-schemas
的操作:在第一个中间件中,抓取django.db.connection
并处理数据库 Select ,而不是模式.我还没有完全考虑过这对于池式/持久性连接意味着什么
我追求的另一个死胡同是特定于租户的表前缀:撇开我需要它们是动态的不谈,即使是全局表前缀也不容易在Django中实现(参见rejected ticket 5000等).
最后,Django multiple database support允许您定义多个命名数据库,并根据实例类型和读/写模式在它们之间进行多路复用.没有帮助,因为没有基于每个请求 Select 数据库的设施.
问题
有人做过类似的事情吗?如果是,你是如何实施的?