Django.db.utils.ProgrammingError: cannot cast type integer to date

Здравствуйте ребята, у меня возникла проблема с PostgreSQL при развертывании из docker. Ошибка:

django.db.utils.ProgrammingError: cannot cast type integer to date
[2022-06-01 09:06:04] LINE 1: ...a_playlist" ALTER COLUMN "year" TYPE date USING "year"::date

Это мой файл миграции : class Migration(migrations.Migration):

dependencies = [
    ('multimedia', '0004_track_track'),
]

operations = [
    migrations.AlterField(
        model_name='playlist',
        name='year',
        field=models.DateField(blank=True, null=True),
    ),
    migrations.AlterField(
        model_name='track',
        name='year',
        field=models.DateField(blank=True, null=True),
    ),
]

Как я могу решить эту проблему? Спасибо!

То, с чем вы столкнулись, может быть решено следующим образом:

Предположим, что ваши модели :

class Playlist(models.Model):
    ...
    year = models.IntegerField(...)
    ...

class Track(models.Model):
    ...
    year = models.IntegerField(...)
    ...

Удалите миграцию

Чтобы избежать путаницы, я бы удалил миграцию, которую вы только что создали. Если вы знакомы с django, вы можете перейти к следующим шагам и отредактировать аргументы AlterField.

Переименуйте свои поля

Измените именование, например temp_year.

class Playlist(models.Model):
    ...
    temp_year = models.IntegerField(...)
    ...

class Track(models.Model):
    ...
    temp_year = models.IntegerField(...)
    ...

Затем выполните ./manage.py makemigrations.

Теперь у вас есть миграция, содержащая переименованные поля.

Добавьте соответствующее поле года

class Playlist(models.Model):
    ...
    temp_year = models.IntegerField(...)
    year = models.DateField(blank=True, null=True)
    ...

class Track(models.Model):
    ...
    temp_year = models.IntegerField(...)
    year = models.DateField(blank=True, null=True)
    ...

Затем выполните ./manage.py makemigrations.

Теперь у вас есть миграция, содержащая поле с нужным вам типом данных.

Передача данных

В файл миграций, только что созданный после последнего migrations.AddField(...), добавьте migrations.RunPython().

некоторые документы о RunPython можно найти здесь

Сразу над классом миграции добавьте функцию, назовем ее map_to_year:

import datetime
def map_to_year(apps, schema_editor):
    Playlist = apps.get_model("your_app_name", "Playlist")
    for playlist in Playlist.objects.all():
        playlist.year = datetime.date(playlist.temp_year,01,01)
        playlist.save(update_fields=["year"])

    Track = apps.get_model("your_app_name", "Track")
    for track in Track.objects.all():
        track.year = datetime.date(track.temp_year,01,01)
        track.save(update_fields=["year"])

class Migration(migrations.Migration):
    ...
    migrations.AddField(...),
    migrations.RunPython(map_to_year)
    ...

Примечание: измените имя_приложения на правильное

Запустите миграции

Теперь, если вы запустите миграцию, она отобразит ваше целое число из temp_year в объект даты из year.

Что дальше?

После перехода вы сможете удалить поле temp_year и запустить makemigrations

Вернуться на верх