2015-10-29 2 views
1

У меня есть приложение Django с заполненной (Postgres) базой данных, которая имеет целое поле, которое мне нужно изменить на CharField. Мне нужно начать хранить данные с ведущими нулями в этом поле. Если я запускаю мигрировать (Django 1.8.4), я получаю следующее сообщение об ошибке:Django изменить поле базы данных от integer до CharField

psycopg2.ProgrammingError: operator does not exist: character varying >= integer 

HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 

Я пытался искать в Google, но на самом деле не найти большую помощь. Я действительно не знаю, что я должен здесь делать. Может ли кто-нибудь помочь?

+0

Не можете ли вы создать резервную копию таблицы, сбросить неисправную таблицу, воссоздать ее, а затем повторно импортировать данные? Как утомительно, как кажется; это будет работать. –

+0

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

ответ

0

Первоначально я думал, что было бы простое решение, в котором Django или Postgres автоматически выполнили бы преобразование, но похоже, что это не работает. Я думаю, что некоторые предложения, сделанные другими, могли бы сработать, но я придумал простое решение. Это было сделано в производственной базе данных, поэтому я должен был быть осторожным. Я закончил тем, что добавил поле символов в модель и выполнил миграцию. Затем я запустил небольшой скрипт в оболочке python, который скопировал данные в целочисленном поле, сделал нужное преобразование, а затем написал это в новое поле в той же записи в производственной базе данных.

, например:

members = Members.objects.all() 
for mem in members: 
    mem.memNumStr = str(mem.memNum) 
    ... more data processing here 
    mem.save() 

Так что теперь у меня были данные дублируются в таблице в поле ул и полем Int. Затем я мог бы изменить представления, которые обращались к этому полю, и протестировать его в производственной базе данных, не нарушая старый код. Как только это будет сделано, я могу удалить старое поле int. Немного вовлечен, но довольно простой в конце.

0

Вам нужно будет сгенерировать миграцию схемы. Как вы это сделаете, будет зависеть от какой версии Django вы используете (версии 1.7 и более новые имеют встроенные миграции, более старые версии Django будут использовать south).

Примечание: если эти данные являются производственными данными, вы должны быть очень осторожны с тем, как вы действуете. Удостоверьтесь, что у вас есть известная хорошая копия ваших данных, которую вы можете переустановить, если все становится волосатым. Проверьте свои миграции в непроизводственной среде. Быть. Осторожный!

Что касается преобразования в поле (от IntegerField до CharField) и преобразования значений поля (которое должно быть добавлено к началу нулей) - Django не может сделать это за вас, вам придется писать это вручную. Правильный способ сделать это - использовать команду миграции django.db.migrations.RunPython (see here).

Моим советом было бы создание нескольких миграций; который создает новый IntegerField, my_new_column, а затем записывается в этот новый столбец через RunPython. Затем выполните вторую миграцию, которая удаляет исходный CharField my_old_column и переименовывает my_new_column как my_old_column.

+0

Благодарим вас за подробный (и очень быстрый) ответ, но я придумал решение, которое получилось лучше для меня. Но я думаю, что ваше решение будет информативным для других. Это было для меня. – mpsg

0

заменить

your_field = models.IntegerField() 

с

your_field = models.CharField() 

Затем запустите

python manage.py makemigrations 
python manage.py migrate 

Если есть какие-либо проблемы проверьте файл миграции сгенерированный командой makemigrations. Внесите необходимые изменения.

+0

Вот как я получил ошибку, которую я цитировал в своем вопросе. Я просил разрешения на ошибку, вызванную этим. – mpsg

+0

Показать файл миграции –

Смежные вопросы