Django 1.2中的多数据库配置

20

这应该是一个简单的问题。

我在理解 Django 1.2 新的多数据库特性文档时遇到了一些困难。主要问题是,我似乎找不到如何在模型中实际使用第二个数据库的例子。

当我在 models.py 中定义一个新类时,我如何指定我打算连接哪个数据库?

我的 settings.py 文件中包含类似于 -

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'modules',
        'USER': 'xxx',                      
        'PASSWORD': 'xxx',                  
    },
    'asterisk': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'users',                     
        'USER': 'xxxx',                      
        'PASSWORD': 'xxxx',                  
    }

}

编辑:我像个傻瓜一样阅读有关路由器的文档。如果其他人也遇到了困难,请确保在放弃之前至少读两到三次!

3个回答

25

是的,这有点复杂。

你可以采用多种方式来实现它。基本上,你需要某种方式来指示哪些模型与哪个数据库相关联。

第一种选择

这是我使用的代码,希望能帮到你。

from django.db import connections

class DBRouter(object):
    """A router to control all database operations on models in
    the contrib.auth application"""

    def db_for_read(self, model, **hints):
        m = model.__module__.split('.')
        try:
            d = m[-1]
            if d in connections:
                return d
        except IndexError:
            pass
        return None

    def db_for_write(self, model, **hints):
        m = model.__module__.split('.')
        try:
            d = m[-1]
            if d in connections:
                return d
        except IndexError:
            pass
        return None

    def allow_syncdb(self, db, model):
        "Make sure syncdb doesn't run on anything but default"
        if model._meta.app_label == 'myapp':
            return False
        elif db == 'default':
            return True
        return None

这是一个关于IT技术的翻译内容。具体需要翻译的内容如下:

工作原理是我创建一个文件,该文件名为要使用的数据库名称,其中包含我的模型。在你的情况下,你需要创建一个单独的models样式文件,称为asterisk.py,它与你的应用程序模型位于同一文件夹中。

在你的models.py文件中,你会添加:

from asterisk import *

当你从该模型实际请求记录时,它的工作方式如下:

  1. records = MyModel.object.all()
  2. MyModel 的模块是 myapp.asterisk
  3. 有一个名为“asterisk”的连接,因此请使用它而不是“default”

第二个选项

如果您想要对数据库选择进行每个模型的控制,则可以尝试以下方法:

from django.db import connections

class DBRouter(object):
    """A router to control all database operations on models in
    the contrib.auth application"""

    def db_for_read(self, model, **hints):
        if hasattr(model,'connection_name'):
            return model.connection_name
        return None

    def db_for_write(self, model, **hints):
        if hasattr(model,'connection_name'):
            return model.connection_name
        return None

    def allow_syncdb(self, db, model):
        if hasattr(model,'connection_name'):
            return model.connection_name
        return None

然后对于每个模型:
class MyModel(models.Model):
    connection_name="asterisk"
    #etc...

请注意,我没有测试过这个第二选项。

1
抱歉回复晚了,但这非常有帮助! - HurnsMobile
你好,我已经实现了您的第二个选项。除了allow_syncdb之外,它运行得很好。我将在下面发布一个答案,其中包括一个适用于任何未来搜索者的工作allow_syncdb。 - Rich
谢谢!我曾经试图从Django文档中理解这一点,但却很困难。 - brian buck

8
在Jordan上面的回答中,我想补充一点。对于第二个选项,allow_syncdb方法的正确使用如下:
def allow_syncdb(self, db, model):
    if hasattr(model,'connection_name'):
        return model.connection_name == db
    return db == 'default'

有趣!所以你在模型中设置了connection_name? - Jordan Reiter
是的。它运行得相当不错,除了许多对多字段,我必须指定一个“through”模型,否则Django会在默认数据库中生成“through”表。 - Rich
哇!我一定会记住这个的。干得好,Rich。 - HurnsMobile

3

我可能漏掉了什么,但据我所知,没有任何关于如何定义模型与默认数据库以外的内容的示例。 - HurnsMobile
+1. Django有很好的文档,而且这些文档几乎总是第一要查找的地方。 - Manoj Govindan
3
“Django的文档好吗?”我并没有经常这样发现。通常当我需要理解东西时,我最终会查看源代码,无论是本地托管还是在http://djangoapi.quamquam.org/trunk/上。 - jsh

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