Django 1.2中的多个数据库配置

20 投票
3 回答
3506 浏览
提问于 2025-04-16 03:40

希望这个问题比较简单。

我在理解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 个回答

3

关于自动数据库路由手动选择数据库的文档,难道没有帮助吗?

8

这是对乔丹上面回答的补充。对于第二个选项,allow_syncdb 方法的工作原理如下:

def allow_syncdb(self, db, model):
    if hasattr(model,'connection_name'):
        return model.connection_name == db
    return db == 'default'
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

这个方法是我创建一个文件,文件名就是要使用的数据库名,这个文件里放着我的模型。在你的情况下,你需要创建一个叫 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...

注意,我还没有测试这个第二种选择。

撰写回答