Как чисто перенести BooleanField в CharField

У меня следующая модель:

class Teacher(models.Model)
    tenured = models.BooleanField(default=False)

Я хочу перенести этот BooleanField в CharField с дополнительными опциями ['No', 'Pending', 'Yes']. Например, так:

class Teacher(models.Model)
    TENURE_CHOICES =  [(choice,choice) for choice in ['No', 'Pending', 'Yes']]
    tenured = models.CharField(max_length=7, default='No', choices=TENURE_CHOICES)

Теперь, поскольку у меня уже есть 1000+ записей для этой модели, я хотел бы перевести их из значения Boolean в значение 'Yes'/'No' при миграции.

Как это сделать без необходимости хранить резервную копию этой таблицы и повторно применять ее после миграции? Могу ли я сделать это в процессе миграции?

Мы запускаем приложение с нулевым временем простоя на django, поэтому мы никогда не можем удалить поле в том же развертывании, что и изменить модель, чтобы отразить удаление.

Для миграции мы переименовываем старое поле и добавляем новое. Вы можете использовать этот подход, чтобы сначала переименовать и добавить новое поле с пользовательской миграцией согласно документации https://docs.djangoproject.com/en/4.0/howto/writing-migrations/.

Поэтому вы храните данные до тех пор, пока не убедитесь, что все в порядке.

Когда вы будете удовлетворены, удалите переименованное поле из модели -> разверните -> сделайте миграции -> разверните снова.

Этот вариант является нулевым временем простоя клиента и имеет преимущество в том, что не требует резервного копирования или копии таблицы.

Вы можете создать миграцию с помощью команды makemigrations и булевы значения будут приведены к символам, '1' для True и '0' для False. После этого вы можете написать простую команду для замены всех '0' на 'No' и всех '1' на 'Yes' или даже с уровня БД.

from authorization.models import TestModel
TestModel.objects.create(example_bool=True)
<TestModel: TestModel object (1)>
TestModel.objects.create(example_bool=True)
<TestModel: TestModel object (2)>
TestModel.objects.create(example_bool=True)
<TestModel: TestModel object (3)>
TestModel.objects.create(example_bool=False)
<TestModel: TestModel object (4)>
TestModel.objects.create(example_bool=False)
<TestModel: TestModel object (5)>
for x in TestModel.objects.all():
    print(x.example_bool)

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