首页 > 解决方案 > 在 Django 中为多个数据库创建路由器

问题描述

我正在开发一个 Django 应用程序,其中我需要几个数据库,一个用于系统的每个用户。为此,我定义了这样的数据库:


DATABASES = {
    'default': {},
    'primary': {
        'NAME': 'primary',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'pass',
    },
    'user1': {
        'NAME': 'user1',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'pass',
    },
    'user2': {
        'NAME': 'user2',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'pass',
    },
}

其中数据库user1user2是结构的副本primary

假设我创建了两个超级用户,登录名分别为“superuser1”和“superuser2”。如何定义当记录“superuser1”时数据库“user1”中的数据发生更改,而当记录“superuser2”时数据库“user2”中的数据发生更改?

标签: djangopython-3.x

解决方案


此逻辑可能会跨越您的应用程序。实际上,您将需要创建一个函数,该函数将获取一个用户实例,然后返回一个将映射到数据库的字符串:

DATABASE_USER_MAP = {
    'username1': 'user1',
}

def get_database(user):
    return settings.DATABASE_USER_MAP.get(user.username, 'default')

def some_view(request):
    data = Data.objects.using(get_database(request.user)).all()
    ...

一旦你得到类似的工作,你可以将数据库确定逻辑移动到一个中间件并设置它,request这样你就可以做到:

def some_view(request):
    data = Data.objects.using(request.db).all()
    ...

对此的主要担忧是,它会默认primary而不是错误地迫使您在编写查询时一丝不苟。

您可能想要追求的另一个途径是深入研究 Django 的代码库,以了解数据库路由器的工作原理以及是否可以将请求作为提示发送给路由器。我对此一无所知,所以我不知道这是否可能。但是,如果可能的话,它会消除我提出的担忧。


推荐阅读