如何在Django中为每个"应用程序实例"使用不同的数据库?

toa*_*abi 8 python django database-connection

场景

我们有两个申请.

该app

TheApp是一款令客户喜爱的令人难以置信的应用.每个客户都获得自己 的应用程序实例,这意味着每个客户将使用不同的数据库(名称,用户,密码).应根据请求所在的域确定数据库连接.

req: customerA.foo.tld -> db:(app_cust1, cust1, hunter2)
req: customerB.foo.tld -> db:(app_cust2, cust2, hunter3)
Run Code Online (Sandbox Code Playgroud)

管理申请

应该能够为客户创建/删除TheApp实例.因此,它必须设置新数据库并将配置写入某处.决定将哪个数据库用于传入请求的方法应该运行良好且易于管理.

问题

哪个是决定应该将哪个数据库连接用于实例的最佳方法?什么表现最好?什么尺度最好?

我想出了答案

我读了一些东西,这些是我提出的方法:

(wsgi daemon + settings.py)每个实例

每个客户都将获得自己的settings.py和数据库凭据.这些设置可能会从共享设置文件中继承一些常见内容.

对于每个新设置文件,必须启动应用程序的新wsgi实例.如果我们有很多客户,这可能会严重缩小?另外创建apache vhost文件很难看.

使用'使用'和一个settings.py

我能做到这一点

MyModel.objects.using(THE_CURRENT_DB).all()
Run Code Online (Sandbox Code Playgroud)

THE_CURRENT_DB根据请求设置某个地方(中间件东西?)但到处都要做到这一点似乎很难看.每次客户获取实例时,都必须重写settings.py/app.

一个settings.py +应用程序路由器

我还没有看看我是否可以在路由器中访问有关请求的任何信息,但如果是这样,我可能会决定应该使用settings.py中的哪个dbs.有点像https://docs.djangoproject.com/en/1.3/topics/db/multi-db/#an-example,但不是每个型号,而是每个请求.

修改中间件中的设置

只是想到可能在中间件中更改数据库设置.还没看看Django中间件是如何工作的,那里有什么可能.

有些模糊的其他方式

由于我对Django很新,我可能错过了一些点,或者其中一些只是完全愚蠢和糟糕.你会做什么?

为什么不在一个db中的一切?

好.因为我认为东西的分离是好的.如果发生不好的事情,并不是每个人都会受到影响.

Car*_*res 1

这是显示 django 配置模块(设置)弱点的场景之一。没有“django 支持”的方法可以做到这一点。

我认为您可以选择对代码维护和可移植性影响最小的选项。所以我建议:

  • 使用中间件将用户配置保存在某些数据结构中(支持 django)
  • 使 settings.DATABASE 成为可调用的以从上面获取用户配置(django hack)
  • 使用django多数据库功能访问模型(django支持)