如何为每个“应用程序实例”使用不同的数据库在姜戈?
场景
我们有两个应用程序。
TheApp
TheApp 是一款深受客户喜爱的令人难以置信的应用程序。每个客户都有自己的 应用程序的实例,这意味着每个客户将使用不同的数据库(名称、用户、密码)。数据库连接应根据数据库所在的域来决定 请求进来。
req: customerA.foo.tld -> db:(app_cust1, cust1, hunter2)
req: customerB.foo.tld -> db:(app_cust2, cust2, hunter3)
管理应用程序
应该能够为客户创建/删除 TheApp 实例。因此,它必须设置新数据库并将配置写入某个地方。决定的方式 用于传入请求的数据库应该表现良好并且易于管理。
问题
决定实例应使用哪个数据库连接的最佳方法是什么?执行什么操作 最好的?什么规模最好?
我想出的答案™
我读了一些东西,这些是我想出的方法:
(wsgi 守护进程 + settings.py)每个实例
每个客户都会获得自己的带有数据库凭据的 settings.py。设置 可以从共享设置文件继承一些常见的东西。
对于每个新的设置文件,都必须启动应用程序的新 wsgi 实例。 如果我们有很多客户,这可能会严重影响规模?还创建 apache vhost 文件 很丑。
使用“使用”&一个 settings.py
我可以这样做
MyModel.objects.using(THE_CURRENT_DB).all()
,并根据请求在某处(中间件之类的东西?)设置 THE_CURRENT_DB
。但必须这样做似乎很难看 到处。此外,每次客户获得他的设置时,都必须重写settings.py/app 实例。
一个 settings.py + 应用程序路由器
我还没有查看是否可以访问有关路由器中请求的任何信息, 但如果是这样,我也许可以决定应该使用 settings.py 中的哪个数据库。有点儿 就像 https://docs.djangoproject.com/en/1.3/topics/ db/multi-db/#an-example 但不是每个模型 但根据要求。
修改中间件中的设置
只是想到也许可以在中间件中更改数据库设置。还没有 了解中间件在 Django 中的工作原理以及其中的可能性。
一些晦涩的其他方式
因为我对 Django 还很陌生,所以我可能错过了一些要点,或者其中一些完全是错误的 又傻又坏。 jes^wyou 会怎么做?
为什么不将所有内容都放在一个数据库中呢?
出色地。因为我认为把东西分开是好的。如果发生不好的事情,并不是每个人都会突然受到影响。
The scenario
We have two applications.
TheApp
TheApp is an incredible app which customers love. Each customer gets his own
instance of the application, which means each customer will use a different database (name,user,password). The database connection should be decided on the domain from which the
request comes in.
req: customerA.foo.tld -> db:(app_cust1, cust1, hunter2)
req: customerB.foo.tld -> db:(app_cust2, cust2, hunter3)
Administration application
Should be able to create/delete TheApp instances for the customers. Therefore it has to setup the new database and write the config to somewhere. The way which decides
which db is used for the incoming request should perform well and be easy manageable.
The Question
Which is the best way to decide which database connection should be used for an instance? What performs
the best? What scales best?
Answers I came up with™
I read stuff and those are the ways I came up with:
(wsgi daemon + settings.py) per instance
Each customer will get his own settings.py with the database credentials. The settings
may inherit some common stuff from a shared settings file.
For each new setting file a new wsgi instance of the application has to be started.
This may scale badly if we have many customers? Also creating the apache vhost files
is ugly.
Using 'using' & one settings.py
I could do it like
MyModel.objects.using(THE_CURRENT_DB).all()
and set THE_CURRENT_DB
somewhere (middleware thingy?) per request. But it seems ugly to have to do this
everywhere. Also the settings.py/app has to be rewritten everytime a customer gets his
instance.
One settings.py + Application Router
I didn't yet have a look if I can access any information about the request in the router,
but if so, I maybe could decide which of the dbs in settings.py should be used. Kind of
like https://docs.djangoproject.com/en/1.3/topics/db/multi-db/#an-example but not per model
but per request.
Modify settings in a middleware
Just had the idea that maybe the db setting could be altered in a middleware. Didn't yet have
a look how middleware works in Django and what's possible there.
Some obscure other way
As I'm pretty new with Django I may have missed some points or some of them are just totally
silly and bad. What would jes^wyou do?
Why not everything in one db?
Well. Because I think separation of stuff is good. And if bad things happen not everybody is suddenly affected.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这可以通过中间件和 Postgres 命名空间轻松完成。这是一个快速而肮脏的示例,完全没有错误处理:
启用此中间件后,每个客户都可以拥有完全独立的数据,并且无需任何操作即可使其工作。不过,有一些事情需要了解:
This is easily done with middleware and Postgres namespaces. Here is a quick and dirty example with absolutely no error handling:
With this middleware enabled, each customer can have completely separate data, and no mopery is required to make it work. There are a few things to know, though:
这是显示 django 配置模块(设置)弱点的场景之一。没有“django 支持”的方法可以做到这一点。
我认为您可以选择对代码维护和可移植性影响最小的选项。所以我建议:
That is one of those scenarios that show the weakness of django configuration module (settings). There is no "django supported" way to do that.
I think you could choose to go with an option that has minimal impact to code maintenance and portability. So I suggest to: