3

在 Django 中使用多个数据库时遇到问题。

这是场景:

我有一个 django 项目,它分为两个应用程序:app1app2. App1将负责身份验证和自定义模块(即它有自己的models.py)并且App2是普通的 Web 应用程序(即它有自己models.py的模型)。

Settings.py 看起来像这样:

DATABASE_ROUTERS = ['app1.router.AuthRouter', 'app1.router.App1Router', 'app2.router.App2Router']

DATABASES = {
    'default': {
      [...]
    },
    'app2': {
      [...]
    }
}

如您所见,我有两个数据库(均为 PSQL 9.2),default(用于app1应用程序)和app2(用于app2应用程序),并且我定义了这样的 3 个路由器(1. 用于身份验证,2. 用于app1 model和最后用于app2 model.

app1.router.AuthRouter和的代码app1.router.App1Router如下:

class AuthRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'auth':
                    return 'default'
        return None

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

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

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


class App1Router(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'app1':
                    return 'default'
        return None

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

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

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

问题是,当我这样做时syncdb,它确实正确地创建auth_了表,但它没有创建django_表,这会出错。

[marek@t420 multipledb_test]$ python manage.py syncdb 
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  [more errors coming]
django.db.utils.ProgrammingError: relation "django_content_type" does not exist
LINE 1: ..."."app_label", "django_content_type"."model" FROM "django_co...

你看?没有创建 DJANGO 表 - 不django_admin_log,不django_content_type,不django_session

有什么提示吗?这让我疯了三天!

4

2 回答 2

3

只是一个评论:我的想法是使用一些数据库,它们将在彼此之间进行通信(例如,使用从一个数据库到另一个数据库的外键)。我希望我更仔细地阅读文档:

跨数据库关系 Django 目前不支持外键或跨多个数据库的多对多关系。如果您使用路由器将模型分区到不同的数据库,则这些模型定义的任何外键和多对多关系必须在单个数据库内部。

所有这些混乱都是徒劳的,因为完整性约束不允许在多个数据库上使用任何关系。

于 2014-01-16T10:00:37.630 回答
1

这篇文章对我有帮助:http: //diegobz.net/2011/02/10/django-database-router-using-settings/

解决方案是这样的:

  1. 仅使用一个路由器,此路由器将处理应用程序 2 - 路由器app2.router.App2Router,而不是任何用于默认数据库的路由器。默认数据库的路由器可以正常工作。

  2. 将其更改app2.router.App2Router为看起来像提供的帖子开头的链接中的代码。仅执行第 1 步就可以正确创建表(通过运行) auth_,但不幸的是,所有模型表都被创建到默认数据库(即来自 的表)。改变使一切正常。django_syncdbapp2app2.router.App2Router

  3. 更改settings.py为如下所示:

    DATABASE_ROUTERS = ['app2.router.DatabaseAppsRouter']

    DATABASE_APPS_MAPPING = {'app2': 'app2'}

现在运行syncdb database=app2创建表到数据库app2并运行syncdb创建所有 django 系统表和自己的app1表到default. 惊人的!

感谢杰森的想法!

于 2014-01-15T15:46:54.130 回答