Множественные миграции Django Postgres: «Миграции не применяются» - PullRequest
0 голосов
/ 30 января 2019

Настройка: одна база данных 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...

1 Ответ

0 голосов
/ 31 января 2019

Решение моих проблем состоит из двух частей.

Получение миграции для работы на TravisCI

Обнаружив невероятную функцию поиска репозитория GitHub, я искал любое использование CREATE SCHEMA <schema_name> в любом *Файл 1006 *.

Я изменил эти две строки в before_script моего .travis.yml файла с

- psql -c "CREATE DATABASE travisci;" -U postgres
- psql -c "CREATE SCHEMA other;" -U postgres

на

- psql -c "CREATE DATABASE travisci;" -U postgres
- psql -c "CREATE SCHEMA other;" -d travisci -U postgres

Добавление -d travisci Аргумент привел к корректной миграции обеих схем.

Начало работы миграций на Heroku

Я использовал эту команду для доступа к клиенту SQL для моего приложения Heroku:

heroku pg:psql -a <app_name>

Для меня должно было быть очевидно, почему это не сработает.Вы можете иметь более одной базы данных для приложения Heroku, и я не указал имя базы данных.Сработало использование этой команды:

heroku pg:psql <database_name> -a <app_name>

Также с помощью pgAdmin для создания работающей схемы.

...