最近我下载了django_messages应用(私人用户到用户消息传递django应用)并将其添加到我的django项目中。
settings.py
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'mydjangoapp.mydjangoappdb',
'tastypie',
'gunicorn',
'south',
'relationships',
'pyapns',
'django_messages',
该应用效果很好,与Django配合得很好。但是对于消息传递等功能,数据库可能会变得非常大。我决定创建一个专用数据库来存储所有django_messages数据。
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'django_db',
'USER': 'django_login',
'PASSWORD': 'xxxx',
'HOST': '',
'PORT': '',
},
'message_db': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'django_messagedb',
'USER': 'django_login',
'PASSWORD': 'xxxx',
'HOST': 'XX.XXX.XX.XXX',
'PORT': '5432',
}
DATABASE_ROUTERS = ['mydjangoapp.messagerouter.MessageRouter']
只是为了澄清,这是我的 messagerouter.py
class MessageRouter(object):
"""
A custom router written by Riegie to
control all database operations on models in the
django_messages application
"""
def db_for_read(self, model, **hints):
"""
Attempts to read django_messages models go to
message_db.
"""
if model._meta.app_label == 'django_messages':
return 'message_db'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write django_messages models to go to
message_db.
"""
if model._meta.app_label == 'django_messages':
return 'message_db'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the django_messages.
"""
if obj1._meta.app_label == 'django_messages' or \
obj2._meta.app_label == 'django_messages':
return True
return None
def allow_syncdb(self, db, model):
"""
Make sure the django_messages app only appears in the
'message_db" database.
"""
if db == 'message_db':
return model._meta.app_label == 'django_messages'
elif model._meta.app_label == 'django_messages':
return False
return None
如您所见,我有两个数据库,一个在运行Django的本地计算机上,另一个在远程计算机上。开箱即用,安装后,django_messages自然会在默认数据库上创建表。但是,我希望它只在“message_db”数据库上创建表。
我查看了Multi-db Setup Django文档,但它详细介绍了Master / Slave配置。我使用了Auth Router示例并创建了messagerouter.py。一切都同步,我没有错误。
但是当我检查远程数据库时,该表不存在!这是为什么?是因为不可能与Django用户建立远程外键表关系吗?
更新
所以我设法使用以下命令将Django_messages应用程序同步到其他数据库: ./ manage.py syncdb --database = message_db 。这很棒。但是,当我从Django管理页面访问应用程序时,我收到以下错误:
DatabaseError at /admin/django_messages/message/
relation "django_messages_message" does not exist
LINE 1: SELECT COUNT(*) FROM "django_messages_message"
我发现这个错误很奇怪,因为我可以通过pgadmin III在另一台服务器上看到该表。所以同步工作正常,但现在看来Django无法识别该表。我在使用messagerouter.py做错了吗?
答案 0 :(得分:2)
因此,经过大量的研究,我终于遇到了这个,我希望我早些时候见过它。 Django不支持跨数据库关系:https://docs.djangoproject.com/en/dev/topics/db/multi-db/#no-cross-database-relations
正如它所述: Django目前不提供跨越多个数据库的外键或多对多关系的任何支持。如果您已使用路由器将模型分区到不同的数据库,则由这些模型定义的任何外键和多对多关系必须位于单个数据库的内部。
这是因为参照完整性。为了维护两个对象之间的关系,Django需要知道相关对象的主键是有效的。如果主键存储在单独的数据库中,则无法轻松评估主键的有效性。
如果您将Postgres,Oracle或MySQL与InnoDB一起使用,则会在数据库完整性级别强制执行 - 数据库级别的键约束会阻止创建无法验证的关系。
但是,如果您将SQLite或MySQL与MyISAM表一起使用,则不存在强制参照完整性;因此,您可以“伪造”跨数据库外键。但是,Django并未正式支持此配置。
希望这个答案可以帮助你们解决许多问题。
答案 1 :(得分:2)
我也发现了这个Django补丁:https://code.djangoproject.com/attachment/ticket/17875/foreignkey-db-using.patch这可能有助于跨数据库关系