Django 数据库路由器

Posted

技术标签:

【中文标题】Django 数据库路由器【英文标题】:Django database router 【发布时间】:2012-03-28 01:09:58 【问题描述】:

我想根据经过身份验证的用户路由(更改)数据库。我查看了docs,但我不知道如何在用户登录时执行此操作...

我正在考虑将带有 database_name 的字段添加到我的自定义 UserProfile,然后我想将此信息传递给数据库路由器,以便进行切换...

我没有任何代码要显示,因为我根本不知道如何实现它。

这篇文章与我之前的post有关。

所以架构应该是这样的:

- Users (containing only the `UserProfile`)
 - user1 (containing the app database)
 - user2 (containing the app database)
 - ...

你能给我指出正确的方向吗?

谢谢! BR

【问题讨论】:

您可能想要编写a middleware function 来检查每个传入的请求,获取当前用户并检查其用户配置文件中的标志,并相应地进行路由。 数据库和用户是什么关系?是横向拆分用户表,还是使用不同的DB为不同的用户进行模型映射? 参考 [this][1] 帖子了解如何使用路由器 [1]:***.com/questions/12352360/… 【参考方案1】:

请参阅this 帖子了解如何使用路由器

DATABASE_ROUTERS = ['CustomDatabaseRouter',] #a setting that Django understands.

class CustomDatabaseRouter(object):

  def db_for_read(self, model, **hints):
     site_name = get_current_site()
     if site_name  in ['site1']:
         return 'db1'
     if site_name in ['site2']:
        return 'db2'
     return 'default'

  def db_for_write(self, model, **hints):
     site_name = get_current_site()
     if site_name  in ['site1']:
         return 'db1'
     if site_name in ['site2']:
        return 'db2'
     return 'default'

  def allow_syncdb(self, model, **hints):
     site_name = get_current_site()
     if site_name in ['site1'] and db == 'db1':
         return True
     if site_name in ['site2'] and db == 'db2':
        return True
     return False

【讨论】:

【参考方案2】:

一般来说,多租户在不扭曲 django 的情况下有点难以实现,即使它是 SaaS 应用程序中的典型请求。这是一个描述approach 的链接,在与我合作的公司开发的那个有点不同,它破解了 contrib.sites,但数据库部分非常相似。

简而言之,如果你想要数据库多租户,你将不得不破解 Django ConnectionHandler 来做你想做的事。

【讨论】:

这种方法很好......但我真的不需要子域,而且我对 Django 有点陌生,所以黑客攻击有点问题。

以上是关于Django 数据库路由器的主要内容,如果未能解决你的问题,请参考以下文章

使用数据库路由器在应用程序 Django 之间共享(mysql)数据库

Django基于模型表路由到数据库

django 多数据库路由不适用于多个模式

Django 基础,项目创建,URL路由,数据库操作

Django之路由系统

Django 大神带你飞系列~走进Django