Ошибка переноса Django: столбца не существует
Python 3, Django 1.8.5, Postgres
У меня есть модель Sites
, которая работает нормально. Недавно я попытался добавить поле, airport_code и перенести данные.
class Site(BaseModel):
objects = SiteManager()
name = models.CharField(max_length=200, unique=True)
domain = models.CharField(max_length=200, unique=True)
weather = models.CharField(max_length=10)
nearby_sites = models.ManyToManyField('self', symmetrical=False, blank=True)
users = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
facebook = models.URLField(max_length=200)
twitter = models.URLField(max_length=200)
header_override = models.TextField(blank=True)
email_header_override = models.TextField(blank=True)
timely_site_tag_id = models.IntegerField()
timely_featured_tag_id = models.IntegerField()
timely_domain = models.CharField(max_length=255)
sitemap_public_id = models.CharField(max_length=255)
state = models.CharField(max_length=24)
airport_code = JSONField()
Однако, когда я запустил makemigrations
, я получил сообщение об ошибке:
django.db.utils.ProgrammingError: column sites_site.airport_code does not exist
LINE 1: ..._site"."sitemap_public_id", "sites_site"."state", "sites_sit...
Конечно, это не имеет смысла, потому что столбец, очевидно, не существует, когда я пытаюсь создать его в процессе миграции.
Я видел много вопросов об этой ошибке в переполнении стека, которые остались без ответа или у вас есть решение вручную создать файл миграции или уничтожить и перестроить базу данных. Это нехорошее решение.
Ответы
Ответ 1
Эта ошибка была решена для меня, комментируя панель инструментов отладки django из INSTALLED_APPS в settings.py. Я не уверен, почему панель инструментов отладки является виновником, но после того, как я прокомментировал это, я смог запустить makemigrations
и migrate
без проблем.
Надеясь, что это помогает кому-то, поскольку я провел двенадцать часов, пытаясь понять это.
Ответ 2
После запуска makemigrations, не забудьте пройти трассировку стека шаг за шагом.
В моем случае я заметил, что он отслеживается путем вызова формы, содержащейся в form.py, в совершенно другом приложении, которое вызвало вызов модели, с которой я пытался создать новую миграцию.
Перемещение класса Form из формы .py в view.py устраняет проблему.
Ответ 3
В моем случае это было связано с тем, что у меня было установлено ограничение unique_together.
Когда я захотел удалить поле, автоматически сгенерированная миграция попыталась удалить поле перед удалением ограничения unique_together.
То, что мне нужно было сделать, это вручную переместить ограничение миграций.AlterUniqueTogether в файле миграции, так что django сначала удаляет ограничение, прежде чем пытаться удалить поле.
Я надеюсь, что это может кому-то помочь.
Ответ 4
Я столкнулся с этой проблемой, и ответ @Nexus помог. Я думал, что предоставлю подробности моего конкретного случая здесь, чтобы лучше проиллюстрировать причину проблемы. Это кажется мне потенциальной ошибкой.
У меня есть модель Brand
следующим образом:
class Brand(BaseModelClass):
name = CharField(max_length=256, unique=True)
website = ForeignKey(URL, on_delete=CASCADE, null=True, blank=True)
Я запустил python manage.py makemigrations
после добавления Boolean
поля следующим образом:
class Brand(BaseModelClass):
name = CharField(max_length=256, unique=True)
website = ForeignKey(URL, on_delete=CASCADE, null=True, blank=True)
trusted = Boolean(default=True)
При выполнении команды makemigrations
я получил ошибку, похожую на OP:
django.db.utils.ProgrammingError: column appname_brand.trusted does not exist
По предложению @Nexus, я прошёл стэк-трассировку, построчно, предполагая, что это не какая-то основная проблема с Django. Оказывается, в одном из файлов forms.py
меня было следующее:
choices={(str(brand.id), brand.name) for brand in Brand.objects.all()}
Решением было просто закомментировать эту строку, запустить manage.py makemigrations
, а затем запустить manage.py migrate
. После этого я раскомментировал строку, и все и функциональность моих форм работали так же, как и раньше.
Ответ 5
У меня та же проблема (столбец не существует), но когда я пытаюсь запустить migrate
не с makemigrations
И вот как решить эту проблему:
-
Войдите в систему как пользователь postgres (мой пользователь называется posgres):
sudo -i -u postgres
-
Откройте терминал SQL и подключитесь к вашей базе данных:
psql -d database_name
-
Перечислите свою таблицу и найдите таблицы, связанные с этим приложением:
\dt
-
Отбросьте их (рассмотрите порядок удаления с отношениями):
DROP TABLE tablename ;
- Перечислите запись миграции, вы увидите, что примененные миграции классифицированы так:
id | приложение | имя | прикладная
- + ------ + -------- + --------- +
SELECT * FROM django_migrations;
-
Удалить строки миграции этого приложения (вы можете удалить по идентификатору или по приложению, с приложением не забывайте "кавычки"):
DELETE FROM django_migrations WHERE app='your_app';
-
Выйдите из системы и запустите ваши миграции (возможно, запустите makemigrations в вашем случае):
python manage.py migrate --settings=your.settings.module_if_any
Примечание: возможно, что в вашем случае вам не придется отбрасывать все таблицы этого приложения, а не все миграции, а только те модели, которые вызывают проблему.
Я хотел бы, чтобы это могло помочь.
Ответ 6
Я столкнулся с этой проблемой недавно после обновления до Django 1.11. Я хотел навсегда решить эту проблему, чтобы мне не приходилось комментировать/раскомментировать код каждый раз, когда я запускаю миграцию на столе, поэтому мой подход:
from django.db.utils import ProgrammingError as AvoidDataMigrationError
try:
... do stuff that breaks migrations
except AvoidDataMigrationError:
pass
Я переименую исключение во время импорта в AvoidDataMigrationError
чтобы было понятно, почему оно там.
Ответ 7
Убедитесь, что вы не выполняете никаких запросов при загрузке приложения!, например. в:
class A:
field = fn_that_makes_query()
При запуске migrate
или makemigrations
Django выполняет системные проверки, которые загружают все приложение, поэтому, если в ходе этого процесса будут выполнены какие-либо запросы, использующие добавленные/измененные поля БД, вы столкнетесь с непредвиденными обстоятельствами, потому что вы пытаетесь получить доступ к файлам базы данных, которых еще нет.
Ответ 8
Запустите эту проблему после переноса моей базы данных postgres на другой сервер. Как-то я испортил базу данных и не смог обновить мою модель с помощью нового класса UserProfile.
Я решил проблему создания начальной миграции для существующей схемы:
- Очистите таблицу
django_migrations
: delete from django_migrations;
командой DELETE FROM django_migrations WHERE app='my_app';
- Для каждого приложения удалите его папку
migrations
: rm -rf <app>/migrations/
- Reset миграции для "встроенных" приложений:
python manage.py migrate --fake
- Для каждого запуска приложения:
python manage.py makemigrations <app>
. Позаботьтесь о зависимостях (модели с ForeignKey должны запускаться после их родительской модели).
- Наконец:
python manage.py migrate --fake-initial
Получил его здесь: fooobar.com/questions/96343/...
PS Я не уверен, что это имело отношение к разрешению проблемы, но, во-первых, я отбросил таблицу в postgresql, которая вызвала ошибку, и закомментировала класс UserProfile в моделях.
в оболочке:
sudo -su postgres
psql databse_name
DROP TABLE table_name;
models.py:
#class UserProfile(models.Model):
#user = models.OneToOneField(settings.AUTH_USER_MODEL, unique=True, primary_key=True, on_delete=models.CASCADE, related_name='user_profile')
#avatar = ThumbnailerImageField(upload_to='profile_images', blank=True)
#country = models.CharField(max_length = 128)
Ответ 9
Застрял в этом вопросе недавно.
В моем случае я добавил ссылку на несуществующее поле в коде, затем пришел к файлу модели и добавил новое поле, затем попытался запустить команду makemigrations
которая makemigrations
вышеуказанную ошибку.
Таким образом, я пошел к трассировке стека до конца и обнаружил, что проблема заключается в добавлении новой ссылки. прокомментировал это, запустил makemigrations
и вуаля.
Ответ 10
Просто сейчас была та же ошибка, когда я пытался перенести SingletonModel, чтобы фактически содержать необходимые поля.
Причиной ошибки было то, что моя Модель A использовала некоторые поля этой модели SingletonModel (в качестве настраиваемых значений). И во время создания модели А в процессе миграции это явно не могло гарантировать, что моя миграция была безопасной.
У коллеги была замечательная идея. Сделайте значение по умолчанию для поля вызовом функции, и, следовательно, ленивым.
Пример:
class A (models.Model):
default_value = models.DecimalField(default: lambda: SingletonModel.get_solo().value, ...)
Поэтому мой совет: попробуйте сделать вызов, вызывающий оскорбления (видимый в stacktrace), ленивым.