Dockerized Django приложение не применяет уникальное ограничение - PullRequest
0 голосов
/ 20 июня 2019

У меня есть две проблемы, обе из которых связаны между собой

Выпуск № 1

У моего приложения есть онлайн-база данных Postgres, которую он использует для хранения данных. Поскольку это приложение Dockerized, созданные мной миграции больше не отображаются на локальном хосте, а хранятся в контейнере Docker. Все вопросы, которые я видел до сих пор, похоже, не имеют проблем с выполнением миграций и добавлением уникального ограничения к одному из полей в таблице.

Я написал шелл-код для запуска скрипта Python, который возвращает мне содержимое файла миграции в окне командной строки. Я смог получить файл миграций, который должен был быть применен, и добавил строку в таблицу django_migrations, чтобы указать то же самое. Затем я запустил makemigrations и мигрировал, но он сказал, что не применены никакие изменения (что заставляет меня думать, что строка, которую я добавил в базу данных, должна была автоматически создаваться django только после того, как он обнаружил миграции самостоятельно, а не указывал файл миграций и просить его внести изменения). Проблема в том, что теперь новые миграции все еще обнаруживают следующее изменение

Migrations for 'mdp':
  db4mdp/mdp/migrations/0012_testing.py
    - Alter field mdp_name on languages

Несмотря на обнаружение этого очевидного «изменения», я получаю следующую ошибку:

return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "mdp_mdp_mdp_fullname_281e4228_uniq" already exists

Я уже проверил на своем сервере postgres, используя pgadmin4, чтобы проверить, действительно ли к нему применено ограничение. И это с именем рядом с отношением, как указано выше. Так почему же Django, очевидно, обнаруживает это как изменение, которое должно быть сделано. Дело в том, что если я сейчас удалю новый файл миграции, который я создал в своем каталоге python, он, вероятно, запустится (так как изменения «очевидно» были внесены в базу данных), но у меня не будет файла миграции, чтобы отслеживать изменений. Мне не нужно, если мне нужно продолжать миграцию сейчас, когда я использую онлайн-базу данных. Я не буду откатывать какие-либо изменения, которые я делаю, и не буду вносить изменения часто. Это всего лишь один / два раза, но я хочу устранить ошибку.

Выпуск № 2

Причина, по которой я использовал «по-видимому» в моей вышеупомянутой проблеме, заключается в том, что хотя раздел ограничений в моей общедоступной схеме показывает мне, что ограничения по какой-то причине были применены, когда я пытаюсь создать новую запись в моей таблице с неуникальная строка в поле, которое я определил как уникальное, оно позволяет создавать его в любом случае.

Ответы [ 2 ]

1 голос
/ 20 июня 2019

Вы никогда ничего не добавляете вручную в таблицу django_migrations.Пусть Джанго сделает это.Если он этого не делает, несмотря ни на что, ваш код не готов к работе.Я понимаю, что вы занимаетесь разработкой в ​​докере.Когда вы делаете это, вы монтируете свой док-том на локальный том.Так как вы не установили это, ваши мигранты не будут отображаться на местном уровне.См. Тома .Это должно решить ваши проблемы.

0 голосов
/ 04 июля 2019

Для любого, кто пытается найти альтернативное решение этой проблемы, кроме монтирования томов из-за нехватки времени, этот ответ может помочь, но @deosha по-прежнему является правильным способом решения этой проблемы.Я исправил проблему, удалив все мои таблицы и строки, соответствующие миграциям, в мое конкретное приложение (нет необходимости удалять таблицы аутентификации и т. Д., Потому что вы не будете удалять строки, соответствующие таблицам в таблице django_migrations).После этого я использовал следующее в сценарии оболочки, вызываемом моим Dockerfile.

python manage.py makemigrations --name testing
python testing_migrations.py

Это необходимо назвать для следующего шага.После этой строки кода я запустил скрипт python testing_migrations, который содержит следующий код:

import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
migrations_file = os.path.join(BASE_DIR, '<path_to_new_migration_file>')
with open(migrations_file, 'r') as file:
    print(file.read())

Обычно первая созданная для приложения миграция будет /0001_testing.py (именно поэтому она называетсянадо раньше).Поскольку содержимое этого файла видно контейнеру, когда он запущен и работает, вы сможете распечатать содержимое файла.Затем выполните команду migrate.Это создает столбец в таблице django_migrations, который заставляет django показывать, что миграция была применена.Однако на вашем локальном компьютере этот файл миграции не существует.Поэтому скопируйте содержимое файла из приведенного выше оператора печати и поместите его в файл .py с тем же именем, как упомянуто выше, и сохраните его в указанной выше папке миграций на локальном устройстве.

Вы можетеследуйте этому методу для всех последовательных миграций, повторяя процесс и увеличивая число в файле testing_migrations по мере необходимости.

Сокращение миграций после завершения создания таблицы поможет.Если вы делаете все это в разработке, и у вас нет требования откатывать изменения в схеме базы данных, просто поместите это в рабочий процесс после удаления всех файлов миграции и строк в таблице django_migrations, соответствующих вашему приложению, как это было сделано изначально,Удалите таблицы и дайте вашему первому новому файлу миграции заново создать их, а затем снова импортируйте данные.

Это не рекомендуемый метод.Используйте деошу, если у вас нет времени.

...