【问题标题】:Multiple Django Databases - Map Model to Database in Same Application多个 Django 数据库 - 将模型映射到同一应用程序中的数据库
【发布时间】:2013-11-23 11:41:27
【问题描述】:

我已经到处寻找解决方案,但找不到任何东西。

我有一个 Django 项目、一个应用程序、两个模型和两个数据库。我希望一个模型能够专门与一个数据库说话和同步。这是我尝试过的:

设置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'database_a',                      # Or path to database file if using sqlite3.
        # The following settings are not used with sqlite3:
        'USER': 'user',
        'PASSWORD': 'xxxxxx',
        'HOST': 'localhost',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
        'PORT': '',                      # Set to empty string for default.
    },
    'applicationb_db': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_b',
        'USER': 'user',
        'PASSWORD': 'xxxxxx',
        'HOST': 'localhost',
        'PORT': '',                 
    },
}
DATABASE_ROUTERS = ['fanmode4.router.ApiRouter']

模型

from django.db import models

class TestModelA(models.Model):
    testid = models.CharField(max_length=200)
    class Meta:
        db_table = 'test_model_a'

class TestModelB(models.Model):
    testid = models.CharField(max_length=200)
    class Meta:
        db_table = 'test_model_b'
        app_label = 'application_b'

路由器

class ApiRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'application_b':
            return 'applicationb_db'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'application_b':
            return 'applicationb_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'application_b' or \
           obj2._meta.app_label == 'application_b':
           return True
        return None

    def allow_syncdb(self, db, model):
        if db == 'applicationb_db':
            return model._meta.app_label == 'application_b'
        elif model._meta.app_label == 'application_b':
            return False
        return None

应用程序名称是“api”。基本上使用此设置,如果我同步数据库,它将仅在默认数据库上同步。如果我同步指定第二个数据库python manage.py syncdb --database=applicationb_db 的数据库,它不会将任何内容同步到第二个数据库。

我只是想实现以下目标:

  • TestModelA 的所有内容都转到默认数据库
  • TestModelB 的所有内容都转到 applicationb_db 数据库
  • 其他所有内容都转到默认数据库

【问题讨论】:

    标签: python database django django-models django-database


    【解决方案1】:

    您可以使用model 代替model._meta.app_label 来检查它是哪个模型并返回适当的数据库。

    您可以将路由器更新为:

    class ApiRouter(object):
        def db_for_read(self, model, **hints):
            if model == TestModelB:
                return 'applicationb_db'
            return None
    
        def db_for_write(self, model, **hints):
            if model == TestModelB:
                return 'applicationb_db'
            return None
    
        def allow_relation(self, obj1, obj2, **hints):
            if model == TestModelB:
               return True
            return None
    
        def allow_syncdb(self, db, model):
            if model == TestModelB:
                return True
            else:
                return False
            return None
    

    【讨论】:

    • 嗨@Rohan 感谢您花时间回答。当我尝试您的答案时,我得到“NameError:未定义全局名称'TestModelB'”。如果我尝试将模型名称放在单引号中,它不会同步任何内容。
    • @MarkWinterbottom,在代码中添加from models import TestModelB
    • 您好 Rohan,非常感谢您的帮助。我认为您不能将模型导入路由器类,因为我收到错误“django.core.exceptions.ImproperlyConfigured: Error importing database router ApiRouter: "No module named models"”
    • @MarkWinterbottom,或者您可以将路由器代码中的测试条件更改为if model.__name__ == 'TestModelB'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2010-11-21
    相关资源
    最近更新 更多