Django перейти из поля char в целочисленное поле?

Я изменил одно из своих CharField в models.py ::

models.CharField(max_length=128, blank=True)

в IntegerField ->

models.IntegerField(default=0)

У меня есть данные для этого поля, в основном пустые строки ("") или целые числа в виде строк (например: "10").

Поэтому я хотел бы преобразовать эти строки в целые числа во время миграции. например:: если пустая строка ("") преобразуется в 0, иначе преобразуется в целое число.

Как я могу этого добиться, выполняя команду ./manage.py migrate?

вот файл миграции, созданный с помощью ./manage.py makemigrations ::

# Generated by Django 2.1.2 on 2018-10-25 04:57

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('dashboard', '0002_auto_20181024_1544'),
    ]

    operations = [
        migrations.AlterField(
            model_name='aclpermissions',
            name='ordering',
            field=models.IntegerField(default=0),
        ),
        migrations.AlterField(
            model_name='submenus',
            name='ordering',
            field=models.IntegerField(default=0),
        ),
        migrations.AlterField(
            model_name='subsubmenus',
            name='ordering',
            field=models.IntegerField(default=0),
        ),
    ]

Когда я запускаю ./manage.py migrate, я получаю ошибку:

psycopg2.DataError: invalid input syntax for integer: ""

потому что есть поля с пустыми строками "".

Итак, я хочу преобразовать пустые строки ("") в 0.

Вы изменили одно из моих CharField на IntegerField. Который из? В вашем файле миграции показано, что вы изменили 3 поля.

Red Cricket 26.10.2018 06:23

@RedCricket я меняю 3 поля на целочисленное. Я решил проблему, обновив все empty strings в базе данных до 0. теперь команда ./manage.py migrate работала нормально.

suhailvs 26.10.2018 06:34

вы имеете в виду, что вы обновили все пустые значения до строки "0"?

Red Cricket 26.10.2018 06:52

@RedCricket да. после обновления я запускаю ./manage.py migrate, который работал.

suhailvs 26.10.2018 07:02

Я бы сначала создал 3 новых поля и написал перенос данных, а затем запустил вторую миграцию, которая переименовала эти 3 поля обратно.

Selcuk 26.10.2018 07:05

@Selcuk Я думаю, что создание новых полей не требуется, поскольку команда migrate выполнит эту работу.

suhailvs 26.10.2018 07:43
4
6
2 363
2

Ответы 2

Char / OLD:

email_type = models.CharField(max_length=50, default=None)

Измените его на Int / New:

email_type = models.IntegerField(default=None)
  • python manage.py makemigration

Способ изменения:

  1. Потеряв данные (простой способ)

Revert migration to previous version

  1. Без потери данных (сложнее)

Open Python shell or Write a script to -- chanage each values of 'email_type' to numbers (like 0, 1, 2, 3...)

А потом

  • python manage.py переносить

Для других, которые столкнутся с этим, вы можете добавить функцию, которая будет запускаться перед другими операциями миграции:

class Migration(migrations.Migration):

    def blank_to_zero(apps, schema_editor):
        AclPermissions = apps.get_model('dashboard', 'AclPermissions')
        SubMenus = apps.get_model('dashboard', 'SubMenus')
        SubSubMenus = apps.get_model('dashboard', 'SubSubMenus')

        for obj in AclPermissions.objects.filter(ordering=''):
            obj.ordering = 0
            obj.save()

        for obj in SubMenus.objects.filter(ordering=''):
            obj.ordering = 0
            obj.save()

        for obj in SubSubMenus.objects.filter(ordering=''):
            obj.ordering = 0
            obj.save()

    dependencies = [
        ('dashboard', '0002_auto_20181024_1544'),
    ]

    operations = [
        migrations.RunPython(blank_to_zero),

        migrations.AlterField(... 
        # the rest of your operations
    ]

См. https://docs.djangoproject.com/en/dev/topics/migrations/#data-migrations для информации о редактировании миграции данных.

Сведите к одному запросу для каждой модели: AclPermissions.objects.filter(ordering='').update(ordering=0‌​). Сэкономит много времени, если объектов много.

Huon Imberger 13.01.2021 00:15

Другие вопросы по теме