Django ORM, CharField и blank = True
Документация Django вполне понятна для хранения пустых строк как "", а не NULL на уровне базы данных (поэтому существует только один возможный формат для пустых данных):
Обратите внимание, что пустые значения строки всегда будут храниться как пустые строки, а не как NULL. Используйте только null = True для нестрочных полей, таких как целые числа, логические значения и даты. Для обоих типов полей вам также необходимо установить blank = True, если вы хотите разрешить пустые значения в формах, поскольку нулевой параметр влияет только на хранилище базы данных (см. Пробел).
Тем не менее, после добавления нового поля, я начал сталкиваться с IntegrityErrors в новом поле (номер телефона).
Значение null в столбце "phone_number" нарушает ненулевое ограничение
Эта модель выглядит так с новым полем (я выполнил миграцию через юг):
class Person(models.Model):
user = models.ForeignKey(User)
description = models.TextField(blank=True)
phone_number = models.CharField(blank=True)
С тех пор я (временно) решил проблему, установив null = True в phone_number, но теперь у меня есть сотни записей с пустыми строками и одно значение NULL в моей базе данных. (Я также попытался добавить default = '' в поле phone_number, но я все еще видел проблемы IntegrityError.)
В прошлом я всегда использовал MySQL, но в этом проекте я использую Postgres. Сгенерированная попытка вставки SQL:
'INSERT INTO "people_person" ("user_id", "description", "gender", "birthdate", "default_image_id", "zip_code", "beta_status") VALUES (%s, %s, %s, %s, %s, %s, %s) RETURNING "people_person"."id"'
.
Я ожидал, что Django будет вставлять пустую строку в столбец "phone_number", но, похоже, это не так. Другая вещь, которую я мог ожидать, - это Django, чтобы включить SET DEFAULT в оператор CREATE TABLE, но это не так. Поэтому Postgres рассердился на NOT NULL в этой колонке.
Спасибо!
Ответы
Ответ 1
Как обычно бывает с проблемами, которые кажутся трудноразрешимыми, проблема была ошибкой пользователя.
В моем приложении было две точки входа - два файла WSGI, но только одна база кода. Обычно Apache перезагружает ваш код только в том случае, если файл затронут. Мое развертывание script касалось только одного из этих файлов WSGI - это означало, что люди, которые дошли до моего сайта через другой файл WSGI, все еще видели старый код. Хуже того, база данных была изменена в соответствии с этим старым кодом, но модели были такими же, как и раньше.
Это, в свою очередь, вызвало проблемы IntegrityError
. Django не знал о поле phone_number
, поэтому, несмотря на то, что я установил blank=True
, Django не прилагал усилий, чтобы вставить пустое значение, - и, конечно, база данных считала, что это означает NULL.
Это вызвало ряд различных ошибок отслеживания, включая указанную выше ошибку.
Удивительно, как часто очень сложные проблемы, подобные этим, вызваны глупыми незначительными упущениями - как развернуть script, я написал 2 месяца назад и забыл обновить.
Спасибо за чтение людей, я поддержал другие ответы, но мне нужно принять мои, поскольку это было в конечном итоге решение.
Ответ 2
Я обнаружил, что если вы явно установите значение поля None
, вы все равно получите эти ошибки. Другими словами, приложение default=
применяется, как только вы создаете объект python, а затем, когда вы сохраняете его в базе данных.
Я предполагаю, что это разумно, но это было немного неожиданно.