【发布时间】:2015-07-25 10:28:08
【问题描述】:
在我的工作中,我们希望运行具有多个数据库的服务器。当您访问像 http://myapp.webpage.com 或 http://other.webpage.com 这样的 URL 时,应该会发生数据库切换。我们只想运行一个服务器实例,并在 HTTP 请求的那一刻切换数据库并返回相应的响应。
我们一直在寻找一种可维护且“对 Django 友好”的解决方案。在我们的调查中,我们找到了可能的方法来做到这一点,但我们没有足够的信息。
选项 1:Django 中间件
django 中间件在服务器每次收到 HTTP 请求时运行。
在此处进行数据库切换可能是最佳选择,但据我所知,使用 django database routers 只允许更改模型或组或模型的数据库。
另一种选择是在中间件中设置django model manager 实例,并强制所有模型从自定义中间件中添加的属性中重新分配
objects属性。-
我的最后一个选择是在中间件接收的请求对象中创建一个新属性,该属性从
李>settings.py返回database alias,并且在每个模型查询中使用 using method。
选项 2:基于类的 View Mixin
创建一个使用过去三个选项的 mixin,但我必须在所有基于类的视图中设置 mixin。如果程序员忘记设置 mixin 并且涉及到生产服务器,数据可能(或停止)在正确的数据库中,我不想冒险。
选项 3:在运行时更改数据库设置
此选项有效,但Is not recommended 风险太大。
更新:
这是如何工作的?
middlewares.py
import django.conf as conf
import os.path
class SelectDB(object):
def process_request(self, request):
print request.META['HTTP_REFERER']
file_database = open("booklog/database.txt", "r")
database = file_database.read(10)
file_database.close()
if database != 'default':
conf.settings.DATABASES['default']['NAME'] = database
任何帮助我们解决问题的信息将不胜感激。
【问题讨论】:
-
这不是数据库路由器存在的全部原因吗?您认为该解决方案有什么缺点?
-
如果我错了请纠正我,但我记得数据库路由器只适用于您定义的某些模型,而不是整个数据库
-
hmmm,这可能是一个愚蠢的问题,但这对于用户#1 在 myapp 的数据库中和用户 #2 同时在其他人的数据库中的鲁棒性有多大?无论风险与否,这都会排除选项#3,不是吗?
-
不,它适用于整个数据库。如果对主数据库的访问变慢,我会使用它回退到备份数据库。它工作透明。
-
@ire_and_curses 我知道这很愚蠢,但是,你能教我一段代码吗?如果我生成模型路由器,如何捕获请求对象以获取 url?我可以知道何时运行模型路由器吗?非常感谢
标签: django django-models django-database django-middleware django-managers