如何在另一个Postgresql数据库中存储特定的Django应用程序
最近我下载了应用程序(一个私人用户对用户的消息传递django应用程序),并将其添加到我的django项目中 设置.py如何在另一个Postgresql数据库中存储特定的Django应用程序,django,postgresql,foreign-keys,remote-server,django-apps,Django,Postgresql,Foreign Keys,Remote Server,Django Apps,最近我下载了应用程序(一个私人用户对用户的消息传递django应用程序),并将其添加到我的django项目中 设置.py INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contri
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',
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']
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_消息数据
设置.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',
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']
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
为了澄清,这里是我的messagerouter.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',
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']
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_消息会立即在默认数据库上创建表。但是,我希望它只在“message_db”数据库上创建表
我已经查阅了Django文档,但它详细介绍了主/从配置。我使用了Auth路由器示例并创建了messagerouter.py。一切都同步,我没有收到任何错误
但是,当我检查远程数据库时,表不在那里!为什么呢?是否因为无法与Django用户建立远程外键表关系
更新 因此,我使用以下命令成功地将Django_messages应用程序同步到另一个数据库:/manage.py syncdb--database=message_db。这太棒了。但是,当我从Django admin页面访问应用程序时,出现以下错误:
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可能有问题吗?所以在做了大量研究之后,我终于发现了这个问题,我希望我能早点看到它。Django不支持跨数据库关系: 正如它所说: Django目前不支持外键或跨多个数据库的多对多关系。如果使用路由器将模型划分到不同的数据库,那么由这些模型定义的任何外键和多对多关系都必须位于单个数据库的内部 这是因为引用完整性。为了维护两个对象之间的关系,Django需要知道相关对象的主键是有效的。如果主键存储在单独的数据库中,则无法轻松评估主键的有效性 如果您在InnoDB中使用Postgres、Oracle或MySQL,这将在数据库完整性级别强制执行–数据库级别的键约束会阻止创建无法验证的关系 但是,如果在MyISAM表中使用SQLite或MySQL,则不存在强制引用完整性;因此,您可能能够“伪造”跨数据库外键。但是,Django不正式支持此配置
希望这个答案能帮你们省去很多麻烦。我还发现了这个Django修补程序:这可能有助于跨数据库关系大多数应用程序并不真正支持这一点,而FK关系肯定会成为一个问题。这通常是通过在同一数据库中分配一个单独的表空间并将该表空间放在不同的存储上来处理的。不过,你还是要支持整个事情;一旦你创建了一个表空间,没有这个表空间,主数据库就没用了。@CraigRinger谢谢你的快速回复,是的,我也认为这会是个问题。但再一次,根据Django Auth应用程序,它能够实现这一点。如果Auth应用程序可以使用此设置,为什么django_消息不能使用?在过去的两天里,我一直在想办法,但似乎仍然找不到解决办法。我还编辑了我的问题并添加了一些详细信息,请看一看,期待您的回复,谢谢。