Маршрутизация Django с несколькими базами данных
Я использую ручной выбор db, чтобы справиться с проектом с двумя отдельными dbs. Я определил свои базы данных в настройках. После некоторого дальнейшего чтения кажется, что маршрутизация базы данных - это на самом деле способ пойти с этим. Однако после прочтения документов и некоторых соответствующих сообщений здесь я более смущен, чем когда-либо.
В моих настройках у меня есть:
DATABASES = {
'default': {
....
},
'my_db2': {
....
}
}
DATABASE_ROUTERS = ['myapp2.models.MyDB2Router',]
Я знаю, что мне нужно определить класс маршрутизатора (I подумать в myapp2.models.py) так:
class MyDB2Router(object):
"""A router to control all database operations on models in
the myapp2 application"""
def db_for_read(self, model, **hints):
if model._meta.app_label == 'myapp2':
return 'my_db2'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'myapp2':
return 'my_db2'
return None
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'myapp2' or obj2._meta.app_label == 'myapp2':
return True
return None
def allow_syncdb(self, db, model):
if db == 'my_db2':
return model._meta.app_label == 'myapp2'
elif model._meta.app_label == 'myapp2':
return False
return None
Тогда что? Требуется ли каждая модель meta.app_label или автоматическая?
Кроме того, я все еще получаю сообщение об ошибке:
django.core.exceptions.ImproperlyConfigured: ошибка импорта маршрутизатора базы данных JournalRouter: "невозможно импортировать имя соединения
Может ли кто-нибудь помочь мне понять, что происходит и что происходит не так? Любая помощь очень ценится.
Ответы
Ответ 1
ОК, так что я просто решил свою проблему. Класс маршрутизатора переходит в отдельный файл с именем routers.py в разделе /myapp2. Нет meta.app_label, поскольку я предполагаю, что он автоматически назначается. Надеюсь, это поможет кому-то. Я также документировал процесс здесь.
Ответ 2
Не помог мне, поэтому я немного отлаживал. Может быть, результаты могут сэкономить кому-то боль.:)
Проблема в django 1.4 - это круговая ссылка, которая возникает, когда django пытается импортировать пользовательский класс маршрутизатора.
Это происходит в django.db.utils.ConnectionRouter
. В моем случае приложение __init__.py
импортировало модуль (tastypie.api
, если быть точным), который в свою очередь (и через длинную цепочку) импортировал django.db.models
. Это не плохо само по себе, но models
пытается импортировать connection
из django.db
, и это имеет зависимость от ConnectionRouter
. Именно в этом и началось наше путешествие. Отсюда ошибка.
Это описано как ошибка в django < 1.6 здесь: https://code.djangoproject.com/ticket/20704 и есть небольшой небольшой набор изменений, который должен был зафиксировать его в django 1.6: https://github.com/django/django/commit/6a6bb168be90594a18ab6d62c994889b7e745055
Моим решением было просто переместить routers.py
из каталога приложения в каталог проекта. Никаких неприятных зависимостей нет.
Ответ 3
Еще одна ошибка, чтобы исключить, заключается в том, чтобы импортировать модели в маршрутизаторе, это приведет к той же ошибке, даже если маршрутизатор определен в другом файле.
Ответ 4
Если у вас есть одно приложение, которое использует несколько баз данных, вы можете маршрутизировать их по каждому приложению и на основе таблицы. Например, если ваше приложение является "консольным", и вы хотите, чтобы модель "PoolServers" приходила с другого конца, вы бы поместили это в свой routers.py
class PoolServerRouter(object):
def db_for_read(self, model, **hints):
"Point only reads to poolserver model to 'hamburger'"
if model._meta.app_label == 'console' and model._meta.db_table == 'PoolServers':
return 'hamburger'
return 'default'