2010-09-03 37 views
20

这是一个很容易的问题。多个数据库配置在Django 1.2

我在理解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',     
    } 

} 

编辑:我读的文件上就像一个虚拟路由器。如果其他人正在为此苦苦挣扎,那么请确保在放弃之前阅读它2到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 

这种方式的工作原理是我创建一个文件,使用数据库的名称来保存我的模型。在你的情况下,你会创建一个独立的models风格的文件,名为asterisk.py,它与应用程序的模型位于同一个文件夹中。

在你models.py文件,你会添加

from asterisk import * 

然后当你真正从模型请求的记录,它的工作原理是这样的:

  1. records = MyModel.object.all()
  2. 模块MyModelmyapp.asterisk
  3. 有一个名为“星号”的连接,所以使用 它代替“默认”

第二个选项

如果你想拥有的数据库选择的每个模型的控制,像这样的工作:

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 2010-10-21 16:11:51

+0

嗨,我已经实现了你的第二个选项。除了allow_syncdb以外,它工作得很好。我将在下面发布一个适用于任何未来搜索者的工作allow_syncdb的答案。 – Rich 2011-02-15 08:58:55

+0

非常感谢!我正在尝试从django文档中挖掘出这个dickens。 – 2012-01-18 20:40:38

3

关于automatic database routingmanually selecting a database的文档没有帮助吗?

+0

我可能失去了一些东西,但据我可以告诉有没有如何定义与除了默认的数据库的任何一个模型的例子。 – HurnsMobile 2010-09-03 16:09:15

+0

+1。 Django具有良好的文档和文档几乎总是第一个看的地方。 – 2010-09-03 16:09:18

+1

正如问题所述,我无法理解文档... – HurnsMobile 2010-09-03 16:16:33

8

Jordans附录上面的答案。对于第二个选项,allow_syncdb法正常工作如下:

def allow_syncdb(self, db, model): 
    if hasattr(model,'connection_name'): 
     return model.connection_name == db 
    return db == 'default' 
+0

有趣!所以你在模型中设置connection_name? – 2011-02-16 01:13:07

+0

是的。除了ManyToMany字段,我必须指定'through'模型,否则Django会在默认数据库中生成'through'表。 – Rich 2011-02-17 01:13:30

+0

哇!我一定会对此做一个心理记录。良好的工作丰富。 – HurnsMobile 2011-02-20 23:29:34