Миграция приложения Django только на альтернативную базу данных - PullRequest
0 голосов
/ 21 марта 2019

У меня есть проект Django с несколькими приложениями.Я хочу, чтобы одно из этих приложений (с именем warehouse) перешло в конкретную базу данных (также называемое warehouse), но, похоже, оно не работает так, как я ожидаю.При переносе этого приложения из командной строки (python manage.py migrate warehouse) я получаю сообщение об успешном завершении:

>>> python manage.py migrate warehouse
Operations to perform:
  Apply all migrations: warehouse
Running migrations:
  Applying warehouse.0001_initial... OK

Миграция отображается в базе данных default, что неверно, но таблицы не создаются,что правильно.Если я изменю команду на следующую:

>>> python manage.py migrate warehouse --database=warehouse

, таблицы будут отображаться в моей базе данных warehouse правильно, как и миграция.Как я могу изменить ситуацию так, чтобы первая команда выдавала ошибку или, по крайней мере, указывала, что данное приложение не может быть применено к базе данных по умолчанию?

Вот мои настройки:

База данныхНастройка в settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'projects',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    },
    'warehouse': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'projects-warehouse',
        'USER': 'otheruser',
        'PASSWORD': 'otherpassword',
        'HOST': 'localhost',
        'PORT': '5432',
    },
}

DATABASE_ROUTERS = ['warehouse.dbrouter.WarehouseRouter', 'base.dbrouter.BaseRouter']

dbrouter.py [Warehouse App]

class WarehouseRouter:
    def db_for_read(self, model, **hints):
        if(model._meta.app_label == 'warehouse'):
            return 'warehouse'

        return None

    def db_for_write(self, model, **hints):
        if(model._meta.app_label == 'warehouse'):
            return 'warehouse'

        return None

    def allow_relation(self, obj1, obj2, **hints):
        if(obj1._meta.app_label == 'warehouse' and
           obj2._meta.app_label == 'warehouse'):
            return True

        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if(app_label == 'warehouse'):
            return db == 'warehouse'

        return None

dbrouter.py [Все другие приложения]

class BaseRouter:
    def db_for_read(self, model, **hints):
        return 'default'

    def db_for_write(self, model, **hints):
        return 'default'

    def allow_relation(self, obj1, obj2, **hints):
        if(obj1._state.db == "default" and obj2._state.db == "default"):
            return True

        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        return db == 'default'

1 Ответ

0 голосов
/ 21 марта 2019

Вы используете базы данных для сохранения своих моделей, а Django также использует базы данных для отслеживания миграций, и если вы не укажете имя базы данных при переносе приложения, Django будет использовать базу данных "default" для хранения метаданных миграции..

Это ожидаемое поведение.Когда вы делаете:

>>> python manage.py migrate warehouse

Django сохраняет миграции в базу данных по умолчанию, а таблицы переходят в базу данных warehouse только из-за WarehouseRouter.

, а затем, когда вы делаете:

>>> python manage.py migrate warehouse --database=warehouse

Тогда Django «знает», что он должен поместить миграции в другое место, где находится база данных «по умолчанию».

Я не тестировал, но думаю, что это сработает (миграция и создание таблиц, без записии чтение в / из моделей) даже без WarehouseRouter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...