Django:多个数据库和ContentType

4
我正在创建一个名为“db_manager”的Django项目,并希望创建两个数据库:一个用于db_manager模型,另一个用于核心Django模型(auth、admin、contentTypes、session等)。
首先,我运行迁移以在adw_core数据库中创建核心模型。然后,我运行迁移以在adw_facts数据库中创建db_manager模型。我使用以下命令: python manage.py migrate db_manager --database adw_facts 我设置了路由器,将应用程序指向适当的数据库:
settings.py
DATABASE_ROUTERS = ['data_warehouse.db_routers.DatabaseRouter']

MAP_APPS_TO_DB = {
    'db_manager': 'adw_facts',
    'django.contrib.auth': 'adw_core',
    'django.contrib.sessions': 'adw_core',
}

db_routers.py

class DatabaseRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label in settings.MAP_APPS_TO_DB:
            return settings.MAP_APPS_TO_DB[model._meta.app_label]
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in settings.MAP_APPS_TO_DB:
            return settings.MAP_APPS_TO_DB[model._meta.app_label]
        return None

    def allow_relation(self, obj1, obj2, **hints):
        # Allow any relation between apps that use the same database.
        db_obj1 = settings.MAP_APPS_TO_DB.get(obj1._meta.app_label)
        db_obj2 = settings.MAP_APPS_TO_DB.get(obj2._meta.app_label)
        if db_obj1 and db_obj2:
            if db_obj1 == db_obj2:
                return True
            else:
                return False
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in settings.MAP_APPS_TO_DB:
            return db == settings.MAP_APPS_TO_DB[app_label]
        return None

当我运行迁移以在adw_facts数据库中创建db_manager模型时,会出现以下错误:
运行时错误: 创建新内容类型时出错。请先确保migrate了contenttypes,再尝试单独迁移应用程序。
我确认表'core_db.django_content_type'存在。问题一定是django.contrib.contenttypes应用程序正在尝试为adw_facts db中的db_manager创建contentTypes,但表'core_db.django_content_type'位于adw_core db中。
我不想删除contenttypes应用程序,因为我正在将其与其他Django功能一起使用。
我可以考虑以下解决方案:
1. 为facts模型禁用contenttypes 2. 为facts_db创建第二个contenttypes表
这两种方法都不是很理想。如果您有更好的解决方案,请告诉我。

也许你有充分的理由进行这种分离,但是如果你想要在模型中添加userid字段或者利用用户权限,那么会出现问题,因为Django目前不支持跨数据库连接。 - serg
是的,我开始意识到这不是正确的方法,因为Django对此功能的支持并不好。文档中应该有警告。 - user5791460
@Nico - 目前 Django 文档中有关于多数据库限制的警告。我不知道它存在了多久。 - Tony
我也遇到了同样的问题。我想在另一个数据库中创建一个模型,不打算与主数据库中的其他模型建立任何关系,但是ContentType关系是必须的,而且我还没有找到解决这个问题的方法。 - Gustavo Gonçalves
1个回答

8

我刚遇到了同样的问题(在Django 2.1上)。 根据@Tony提到的文档,似乎需要在每个数据库中复制来自多个Django组件的数据。 以下是对我有用的内容:

def allow_migrate(self, db, app_label, model_name=None, **hints):
    if app_label in ('sites', 'contenttypes', 'auth'):
        return True

    if app_label in settings.MAP_APPS_TO_DB:
        return db == settings.MAP_APPS_TO_DB[app_label]
    return None

感谢提供解决方案。我现在离问题太远了,无法确认是否解决了我遇到的问题。如果其他人确认有帮助,我很乐意将其标记为正确答案。 - user5791460
2
我可以确认,将条件添加到路由器的allow_migrate方法中,始终为sitescontenttypesauth返回True,就像上面演示的那样,对我来说解决了这个问题。 - Ryan Hiebert

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