Django中的多个数据库和多个模型

30

我有两个数据库和两个模型:Admin和user。

我想要将我的模型同步到这两个数据库中;Admin模型同步到数据库A,而user模型同步到数据库B。

如果我将模型路径设置为INSTALLED_APPS并运行syncdb命令,则这两个模型将会同步到默认的数据库。

如果我在syncdb命令中设置数据库,例如sync --database="B",则这两个模型将同步到数据库B。

所以我的问题是,如何将这两个模型同步到两个不同的数据库?


@alecxe - 不是原帖的作者,但你解决了我的问题 :) - whoisearth
2个回答

31

我完全同意 @alecxe 的观点,使用数据库路由是很好的选择。我目前正在使用单个管理员界面来管理多个数据库。请注意,所有数据库的身份验证信息都存储在默认数据库中,因此当您执行 syncdb(不带参数)时。

通用数据库路由器

我发现这个实现非常灵活和有用。

Settings.py

# Define the database manager to setup the various projects
DATABASE_ROUTERS = ['manager.router.DatabaseAppsRouter']
DATABASE_APPS_MAPPING = {'mux_data': 't29_db', 
                         'T50_VATC':'t50_db'}

DATABASES = {
    'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2', 
            'NAME': 'fail_over',                    
            'USER': 'SomeUser',                      
            'PASSWORD': 'SomePassword',                  
            'HOST': '127.0.0.1',                     
            'PORT': '',                      
    },

    't29_db': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2', 
            'NAME': 'mux_stage',                    
            'USER': 'SomeUser',                      
            'PASSWORD': 'SomePassword',                  
            'HOST': '127.0.0.1',                      
            'PORT': '',                      
    },

    't50_db': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2', 
            'NAME': 't50_vatc',                    
            'USER': 'SomeUser',                      
            'PASSWORD': 'SomePassword',                 
            'HOST': '127.0.0.1',                     
            'PORT': '',                      
    },
}

示例模型

# Create your models here.
class Card_Test(models.Model):
    name = models.TextField(max_length=100)
    description = models.TextField(max_length=200)
    units = models.TextField(max_length=500)
    result_tags = models.TextField(max_length=500)

    class Meta:
        app_label = 'mux_data'

    def __unicode__(self):
        return self.name

class Status_Type(models.Model):
    status = models.CharField(max_length=25)

    class Meta:
        app_label = 'mux_data'

    def __unicode__(self):
        return self.status

1
在定义的这两个模型中,您都将app_label设置为“mux_data”。这是有意为之的吗?是要表明这两个模型都将保存到数据库t29_db中吗?因此,如果任何其他模型具有app_label“T50_VATC”,那么它将保存在db t50_db中。 - Vikas Ojha
谢谢。你的回答帮了我很多。 - Vikas Ojha
4
DatabaseAppsRouter这个类应该放在哪里?它应该导入什么? - Kiran K Telukunta
4
截止今日,链接已经失效,答案也无法工作。你应该直接将代码添加到答案中,否则它就不再是一个答案了。 - AivanF.
1
https://web.archive.org/web/20180601203243/http://www.diegobz.net/2011/02/10/django-database-router-using-settings/ - mehmetö
显示剩余2条评论

22
为了定义特定模型使用的特定数据库,您需要定义一个数据库路由器

使用多个数据库的最简单方法是设置数据库路由方案。默认路由方案确保对象保持“粘性”到其原始数据库(即,从foo数据库检索的对象将保存在同一数据库中)。默认路由方案确保如果未指定数据库,则所有查询都回退到默认数据库。

请参见此片段作为示例:http://djangosnippets.org/snippets/2687/

还请参阅:


alecxe,谢谢,但是app_label是什么?我应该在Django模型中设置app_label吗? - kuafu
这并不是很重要,而取决于你如何实现你的路由器。顺便提一下,在 Django 文档中有一个示例,展示了如何使用 app_label 进行路由。 - alecxe
在https://thenewcircle.com/s/post/1242/django_multiple_database_support中,它给出了以下代码:如果model._meta.app_label == 'chinook',则返回'chinookdb'。因此,如果我想让一个模型在chinookdb上操作,我应该在元数据中添加一个app_label,对吗? - kuafu
@young001 是的,如果你按照这篇文章中给出的指示做。 - alecxe
@young001,如果模型是在您的应用程序目录中定义而不是外部定义,则绝对不需要在其元类中声明app_labels。我刚刚按照您描述的方式实现了两个数据库和路由器,在Django 1.8中工作得很好,而没有显式声明。Adam Lewis下面提供的示例并不与此相矛盾,而是一种不同的方法,涉及覆盖默认使用应用程序名称作为app_label的方法,以避免重复的路由器,并且可能使用一个数据库来指定两个或更多应用程序。 - Mike O'Connor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接