Как чисто перенести 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