'How to cleanly migrate BooleanField to CharField
I have the following model:
class Teacher(models.Model)
tenured = models.BooleanField(default=False)
I want to migrate this BooleanField to a CharField with additional options ['No', 'Pending', 'Yes']. Like so:
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)
Now, as I have 1000+ records already present for this model I would like to migrate them from their Boolean value to the 'Yes'/'No' value when migrating.
How would I do this without having to store a backup of this table and reapply after migrations have taken place? Can I do this as part of the migration process?
Solution 1:[1]
You can create migration using makemigrations command and boolean values will be casted to chars, '1' for True and '0' for False. After that you can write simple command to swap all '0' to 'No' and all '1' to 'Yes' or even from DB level.
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
Solution 2:[2]
We run a zero downtime application on django so we can never remove a field in the same deployment as the change the model to reflect the deletion.
To migrate we rename the old field and add the new field You could use this approach to first rename and add the new field with custom migration according to docs https://docs.djangoproject.com/en/4.0/howto/writing-migrations/.
So you keep the data until you are sure everything is fine.
Once you are satisfied remove the renamed field from model -> deploy -> make migrations-> deploy again.
This variant is zero downtime complient and has the benefit of not requiring a backup or a copy of the table.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | TrueGopnik |
| Solution 2 | Dharman |
