Приложение Dockerized Django не применяет уникальное ограничение

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

Проблема №1

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

Я написал код оболочки для запуска скрипта Python, который возвращает мне содержимое файла миграции в окне командной строки. Мне удалось получить файл миграции, который нужно было применить, и добавить строку в таблицу django_migrations, чтобы указать то же самое. Затем я запустил makemigrations и migrate, но он сказал, что никаких изменений не применялось (что наводит меня на мысль, что строка, которую я добавил в базу данных, должна была автоматически создаваться 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, чтобы проверить, действительно ли к нему применено ограничение. И он имеет с именем рядом отношение, как указано выше. Так почему же тогда Джанго, по-видимому, определяет это как изменение, которое необходимо внести. Дело в том, что если я сейчас удалю новый файл миграции, который я создал в своем каталоге python, он, вероятно, запустится (поскольку изменения «очевидно» были внесены в базу данных), но у меня не будет файла миграции, чтобы отслеживать изменений. Мне не нужно, если мне нужно сохранить миграции сейчас, когда я использую онлайн-базу данных. Я не буду откатывать какие-либо изменения, которые я делаю, и не буду вносить изменения слишком часто. Это всего лишь один/два раза, но я хочу устранить ошибку.

Проблема №2

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


person LeroyJD    schedule 20.06.2019    source источник
comment
Я не совсем понимаю ваше описание. Это Docker env в разработке или производстве? Если это prod, вы не должны создавать миграции там.   -  person Daniel Roseman    schedule 20.06.2019
comment
Кто-то работал над этим проектом до меня. Их файлы были отправлены в репозиторий github, который я разветвил, скачал и запустил с помощью докера. Сейчас я вношу изменения во весь проект, но сайт, который я создаю, в настоящее время не запущен и не работает, если вы об этом спрашиваете.   -  person LeroyJD    schedule 20.06.2019


Ответы (2)


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

person deosha    schedule 20.06.2019
comment
Я удалил то, что добавил в таблицу миграции. Я понял, что это неправильный подход, но я знаю о монтировании томов и не думаю, что это решит проблему здесь. Вы видите, что django, кажется, обнаруживает, что я добавляю ограничение unique=True, хотя это обновление уже было сделано в поле, когда я обращаюсь к нему из pgadmin4, как видно из второй ошибки. - person LeroyJD; 20.06.2019
comment
Вы можете изменить models.py, чтобы иметь новые конфигурации таблиц базы данных и повторно запустить миграцию. - person deosha; 20.06.2019
comment
Это то, что я сделал ... прочитайте мой вопрос, я документирую процесс, которому я следовал там. - person LeroyJD; 20.06.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 (именно поэтому ранее было необходимо присвоить ей имя). Поскольку содержимое этого файла видно контейнеру во время его работы, вы сможете распечатать содержимое файла. Затем запустите команду миграции. Это создает столбец в таблице django_migrations, из-за которого django видит, что миграция была применена. Однако на вашем локальном компьютере этот файл миграции не существует. Поэтому скопируйте содержимое файла из приведенного выше оператора печати и поместите его в файл .py с тем же именем, что указано выше, и сохраните его в указанной выше папке миграции на локальном устройстве.

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

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

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

person LeroyJD    schedule 04.07.2019