在Django中使用多个数据库时遇到问题。
以下是该方案:
我有一个django项目,它分为两个应用程序:app1
和app2
。 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
!!!
任何提示?这让我疯狂了三天!
答案 0 :(得分:3)
只是评论: 我的想法是使用一些数据库,这些数据库将在彼此之间进行通信(例如,使用从一个数据库到另一个数据库的外键)。 我希望我更仔细地阅读文档:
跨数据库关系 Django目前不提供跨越多个数据库的外键或多对多关系的任何支持。如果您已使用路由器将模型分区到不同的数据库,则由这些模型定义的任何外键和多对多关系必须位于单个数据库的内部。
所有这些混乱都是无用的,因为完整性约束不允许在多个数据库上使用任何关系。
答案 1 :(得分:1)
这篇文章对我有什么帮助: http://diegobz.net/2011/02/10/django-database-router-using-settings/
解决方案是:
只使用一个路由器,此路由器将负责应用程序2 - 路由器app2.router.App2Router
,而不是任何路由器用于默认数据库。默认数据库的路由器工作正常。
将app2.router.App2Router
看作是提供的帖子开头的该链接中的代码。仅执行步骤1导致正确创建auth_
和django_
表(通过运行syncdb
),但不幸的是,所有MODEL表都创建为默认数据库(即来自{{1}的表) })。改变app2
使一切正常。
将app2.router.App2Router
改为:
DATABASE_ROUTERS = ['app2.router.DatabaseAppsRouter']
DATABASE_APPS_MAPPING = {'app2':'app2'}
现在,运行settings.py
会向数据库syncdb database=app2
创建表,而运行app2
会创建所有django系统表,并将syncdb
表创建为app1
。真棒!
感谢Jason的想法!