4

最近我下载了django_messages应用程序(私人用户到用户消息传递 django 应用程序)并将其添加到我的 django 项目中。

设置.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 数据。

设置.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 文档,但它详细介绍了主/从配置。我使用了 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 做错了什么?

4

2 回答 2

2

所以在做了很多研究之后,我终于遇到了这个,我希望我早点看到它。Django 不支持跨数据库关系:https ://docs.djangoproject.com/en/dev/topics/db/multi-db/#no-cross-database-relations

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

这是因为参照完整性。为了维护两个对象之间的关系,Django 需要知道相关对象的主键是有效的。如果主键存储在单独的数据库中,则无法轻松评估主键的有效性。

如果你在 InnoDB 中使用 Postgres、Oracle 或 MySQL,这是在数据库完整性级别强制执行的——数据库级别的键约束防止创建无法验证的关系。

但是,如果您将 SQLite 或 MySQL 与 MyISAM 表一起使用,则没有强制引用完整性;因此,您可能能够“伪造”跨数据库外键。但是,Django 不正式支持此配置。

希望这个答案可以为你们中的许多人省去麻烦。

于 2013-04-24T19:07:42.953 回答
2

我还发现了这个 Django 补丁:https ://code.djangoproject.com/attachment/ticket/17875/foreignkey-db-using.patch这可能有助于跨数据库关系

于 2013-04-24T19:11:27.957 回答