2013-04-24 2 views
4

Недавно я загрузил приложение django_messages(частный пользователь для обмена сообщениями пользователя django) и добавил его в мой проект django.Как сохранить конкретное приложение Django в другой базе данных Postgresql

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».

Я просмотрел документацию Django Multi-db Setup, но в нем подробно рассказывается о конфигурации Master/Slave. Я использовал пример Auth Router и создал messagerouter.py. Все синхронизируется, и я не получаю ошибок.

enter image description here

При проверке удаленной базы данных, однако, таблица не существует! Почему это? Это связано с тем, что с пользователем Django невозможно иметь отношение удаленного внешнего ключа к таблице?


UPDATE

Так мне удалось синхронизировать приложение 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

Большинство приложений не действительно поддерживают это - и FK отношения, безусловно, будет проблемой. Это, как правило, обрабатывается путем распределения отдельного табличного пространства в пределах одной базы данных и помещения этого табличного пространства в другое хранилище. Тем не менее, вам все равно придется отбросить все это; после создания табличного пространства основная БД бесполезна без этого табличного пространства. –

+0

@CraigRinger благодарит за быстрый ответ, да, я тоже думал, что это будет проблемой. Но опять же, согласно https://docs.djangoproject.com/en/dev/topics/db/multi-db/, приложение Django Auth может это сделать. Если приложение Auth может работать с этой настройкой, почему не может django_messages? Я пытался понять это в течение последних двух дней и все еще не могу найти решение. Я также отредактировал свой вопрос и добавил еще несколько подробностей, пожалуйста, взгляните, ожидая услышать от вас, спасибо. – noahandthewhale

ответ

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.

Надеюсь, что этот ответ спасет многих из вас.