Автоматический дб роутер для миграций в django
Я создаю сайт на платформе Django и хочу иметь отдельные базы данных для некоторых приложений, я создаю гибкий маршрутизатор, который направляет каждое приложение в предопределенную базу данных, это прекрасно работает. Проблема в том, что при переносе моих моделей мне нужно установить --database
параметр каждый раз, и я нахожу это раздражающим и излишним. Также много раз я заливал свою базу данных по умолчанию таблицами из перенесенного приложения (забыв добавить --database
). Я экспериментировал с allow_migrate(...)
функционировать в моем маршрутизаторе, но все, чего я мог добиться, это механизм безопасности, который не будет запускать миграцию, если я забуду указать базу данных Мой вопрос: есть ли способ настроить автоматический выбор базы данных для миграции моделей в Django? Мой подход может быть неправильным, меня удивляет, что никто, кажется, не делал этого раньше.
2 ответа
Я не знаю ни одного способа сделать это автоматически. Тем не менее, простым подходом может быть написание собственной версии migrate
Команда, которая вызывает Джанго migrate
команда несколько раз с соответствующим --database
и аргументы приложения.
По словам автора миграций Django, это сознательное проектное решение, поэтому я не ожидаю, что оно изменится: "Как и в случае с syncdb, миграция выполняется только для одной базы данных за раз, поэтому вы должны выполнять ее отдельно для каждой базы данных, как вы предлагаете. Это по замыслу ".
Для тех, кто столкнулся с проблемой, с которой я столкнулся, вот что я, наконец, решил:
routers.py:
from django.conf import settings
class DatabaseAppsRouter(object):
def db_for_read(self, model, **hints):
# your db routing
def db_for_write(self, model, **hints):
# your db routing
def allow_relation(self, obj1, obj2, **hints):
# your db routing
def allow_syncdb(self, db, model):
# your db routing
def allow_migrate(self, db, app_label, model_name=None, **hints):
if db in settings.DATABASE_APPS_MAPPING.values():
return settings.DATABASE_APPS_MAPPING.get(app_label) == db
elif app_label in settings.DATABASE_APPS_MAPPING:
return False
settings.py
DATABASE_ROUTERS = ['project.routers.DatabaseAppsRouter']
DATABASE_APPS_MAPPING = {'contenttypes': 'default',
'auth': 'default',
'admin': 'default',
'sessions': 'default',
'messages': 'default',
'staticfiles': 'default',
'myapp': 'mydb',
}
эта настройка позволяет мне запускать две команды:
python manage.py migrate
python manage.py migrate --database=mydb
который по-прежнему один ко многим, но по крайней мере сейчас я не могу по ошибке перенести myapp в базу данных по умолчанию, что происходило чаще, чем я хочу допустить.
Предупреждение - напыщенная речь:
До этого момента я находил дизайн Django странным, но очень логичным и удобным для программиста, как и сам Python. Но способ, которым миграции взаимодействуют с несколькими настройками базы данных, действительно неудобен, так легко заполнить базу данных по умолчанию нежелательными таблицами. Обсуждение, связанное Кевином в его ответе, показывает, что я не единственный, кто испытывает подобные трудности.