Почему Django создает мое TextField как varchar в базе данных PostgreSQL?

Джанго 1.7, Питон 3.4.

В моих моделях у меня определено несколько текстовых полей.

Когда я загружаю фикстуру JSON (сгенерированную из дампа SQLite3), она не работает со вторым объектом, в одном из полей которого содержится 515 символов.

Напечатанная ошибка

psycopg2.DataError: value too long for type character varying(500)

Я создал новую базу данных (не просто удаление таблицы, а совершенно новую базу данных), изменил файл settings.py, запустил manage.py syncdb в новой базе данных, создал пользователя и попытался снова загрузить данные, получив ту же ошибку.

При открытии pgAdmin3 все столбцы, определенные как CharField, так и TextField, отображаются как тип character var.

Таким образом, кажется, что TextField игнорируется, а вместо этого создаются CharFields. В документации PostgreSQL явно перечислены как текстовые, так и символьные типы, а длина текста определена как неограниченная. Есть идеи, почему?


person Matthew Pace    schedule 24.09.2014    source источник
comment
Вы уверены, что модель не изменилась и поле по-прежнему является TextField?›   -  person Joseph    schedule 25.09.2014
comment
Тьфу, почему ORM настаивают на установке произвольных ограничений? Django должен просто использовать text или неограниченный varchar.   -  person Craig Ringer    schedule 25.09.2014
comment
@CraigRinger Я согласен, что django и другие должны по умолчанию использовать 95% общего варианта использования, но я понимаю необходимость сохранения небольших и быстрых баз данных для приложений с высокой нагрузкой. Интересно, что Postgres говорит, что использование Text вместо varchar не снижает скорость, но все varchars ограничены, что кажется странным. Если я не делаю что-то конкретное с огромными объемами данных, я буду просто использовать TextField во всех приложениях Django с этого момента.   -  person Matthew Pace    schedule 25.09.2014


Ответы (1)


Я не уверен, в чем была точная причина, но, похоже, она связана с инструментом миграции django, сохраняющим миграции даже в новой базе данных.

Что я сделал, чтобы получить такое поведение:

  • Создайте проект django, затем приложения, используя CharField
  • syncdb, запустить сервер разработки проекта
  • убейте devserver, измените поля на TextField
  • Создайте новую базу данных Postgres, измените settings.py
  • Запустите syncdb, попытайтесь загрузить фикстуры
  • См. рассматриваемую ошибку, проверьте экземпляр БД

Что устранило проблему:

  • Создайте новую базу данных, измените settings.py
  • удалить все миграции в папках приложений/миграций
  • после запуска syncdb также запустите createmigrations и migrate

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

Где-то на последних двух шагах это было исправлено. Будущие люди, наткнувшиеся на это: извините, я не собираюсь продолжать создавать проекты django для дальнейшего тестирования поведения, но, возможно, с помощью этой информации вы сможете исправить свои собственные проблемы с базой данных.

person Matthew Pace    schedule 25.09.2014