django中的多个数据库 - syncdb不会创建django_表

时间:2014-01-15 14:19:50

标签: django django-syncdb

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

以下是该方案:

我有一个django项目,它分为两个应用程序:app1app2App1将负责身份验证和自定义模块(即它有自己的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.AuthRouterapp1.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 !!!

任何提示?这让我疯狂了三天!

2 个答案:

答案 0 :(得分:3)

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

  

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

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

答案 1 :(得分:1)

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

解决方案是:

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

  2. app2.router.App2Router看作是提供的帖子开头的该链接中的代码。仅执行步骤1导致正确创建auth_django_表(通过运行syncdb),但不幸的是,所有MODEL表都创建为默认数据库(即来自{{1}的表) })。改变app2使一切正常。

  3. app2.router.App2Router改为:

    DATABASE_ROUTERS = ['app2.router.DatabaseAppsRouter']

    DATABASE_APPS_MAPPING = {'app2':'app2'}

  4. 现在,运行settings.py会向数据库syncdb database=app2创建表,而运行app2会创建所有django系统表,并将syncdb表创建为app1。真棒!

    感谢Jason的想法!