Настройка: одна база данных Postgres с двумя схемами: «по умолчанию» и «другие».Использование:
Django==2.0.10
psycopg2-binary==2.7.7
(без бинарной версии в производстве)
Конфигурация моей базы данных:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
'options': '-c search_path=django,default',
},
...
'TEST': {
'NAME': 'default',
'DEPENDENCIES': ['other'],
},
'ATOMIC_REQUESTS': True,
},
'other': {
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
'options': '-c search_path=other,default',
},
...
'TEST': {
'NAME': 'other',
'DEPENDENCIES': [],
},
'ATOMIC_REQUESTS': True,
}
}
Действия, предпринятые для новой базы данных:
py manage.py migrate
: работает должным образом, и схема «по умолчанию» переносится правильно. py manage.py migrate --database=other
приводит к: No migrations to apply.
Как ни странно, выполнение этих шагов (опять же в новой базе данных) в обратном порядке работает:
py manage.py migrate --database=other
: работает должным образом, и «другая» схема переносится правильно. py manage.py migrate
приводит к тому, что: работает должным образом, и схема «по умолчанию» переносится правильно.
Я подозреваю, что это как-то связано с таблицей django_migrations
.Я не знаю много об этой таблице, есть ли один на схему Postgres?Или только одна таблица django_migrations
на проектПосле долгих поисков я увидел много предложений по использованию маршрутизаторов баз данных.«Другая» схема должна иметь все те же таблицы, что и схема «по умолчанию», поэтому маршрутизатор в этом случае не поможет.
Я пытался выполнить SQL DELETE FROM django_migrations
после выполнения миграций по умолчаниюа затем запустить миграцию на «другом»;это работает только для первой миграции на новую базу данных, любые последующие попытки миграции приводят к ошибке, так как Django пытается применить уже примененные миграции и вызывает django.db.utils.ProgrammingError: relation "<relation>" already exists
.
Я также пытался поиграться с django.db.migrations.recorder.MigrationRecorder
класс для очистки таблицы миграции между миграцией базы данных 'default' и 'other', опять же, не повезло.
Кроме того, единственный способ, которым я смог запустить мой набор тестов, - это установить 'other'в качестве зависимости для «default» использовать странный факт, что миграция «other» до «default» работает.
Я в недоумении, почему это происходит, я уверен, что что-то упускаю.
Обновление
Предпринимаю те же шаги, что упоминались ранее:
py manage.py migrate
: работает должным образом, и схема «по умолчанию» переносится правильно. py manage.py migrate --database=other
приводит к: No migrations to apply.
После некоторого копания в pgAdmin я запустил следующий SQL
SET search_path TO default
SELECT * FROM django_migrations
, и это вернул таблицуприкладные миграции, как и ожидалось.Затем запустил следующий SQL
SET search_path TO other
SELECT * FROM django_migrations
, и я получил сообщение о том, что отношения "django_migrations" не существует.Таким образом, это отвечает на мой вопрос, касающийся таблицы django_migrations
: по одной на каждую схему, и это, конечно, имеет смысл.
Так что это заставляет меня думать, что Джанго должен смотреть на таблицу django_migrations
изсхема «по умолчанию» при попытке перенести «другую» схему и, таким образом, видит, что «миграции не применяются».Я буду продолжать пытаться решить эту проблему, любые указатели будут иметь большое значение, так как я все еще не уверен, как заставить миграции работать на обеих схемах.
Обновление
Я написал это какответ, но это решение работало только локально, поэтому я добавил его вместо обновления.
Поработав некоторое время над конфигурацией DATABASES
, я наконец понял, что стало причиной проблем, с которыми я столкнулся.Я предоставил список через запятую для каждой опции search_path
, например, так:
DATABASES = {
'default': {
...
'OPTIONS': {
'options': '-c search_path=django,default',
},
...
},
'other': {
...
'OPTIONS': {
'options': '-c search_path=other,default',
},
...
}
}
Моя интерпретация того, что происходит здесь: при запуске py manage.py migrate
на новой базе данных Django увидит, что нетdjango_migrations
Таблица в схеме «по умолчанию», создайте ее, а затем заполните ее при применении миграций.Затем, когда я запускаю py manage.py migrate --database=other
, он будет искать в 'other' для django_migrations
, не найдет его, и тогда он должен выглядеть в 'default', так как это следующее место для поиска в пути поиска.Так как django_migrations
уже существует в схеме «по умолчанию», Django будет использовать эту таблицу, а затем увидит, что «нет применений миграции».Возможно, я здесь не совсем точен, пожалуйста, исправьте меня, если я сказал что-то явно неправильное.
Изменение путей поиска в конфигурации DATABASES
, например, так:
DATABASES = {
'default': {
...
'OPTIONS': {
'options': '-c search_path=default',
},
...
},
'other': {
...
'OPTIONS': {
'options': '-c search_path=other',
},
...
}
}
привел к успешной миграции обеих схем в моей локальной среде.Однако это не работает, когда миграции выполняются на TravisCI или Heroku.Оба из них выдают эту ошибку при переносе «default» или «other»:
Traceback (most recent call last):
File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django/db/backends/utils.py", line 83, in _execute
return self.cursor.execute(sql)
psycopg2.ProgrammingError: no schema has been selected to create in
LINE 1: CREATE TABLE "django_migrations" ("id" serial NOT NULL PRIMA...