问题
I want to change my Model
class Source(models.Model):
release_date = models.DateField()
to
class Source(models.Model):
release_date = models.IntegerField()
as expected, I get an error
django.db.utils.DataError: (1264, "Out of range value for column 'release_date' at row 1")
What I actually want is, to only save the year in the IntegerField
as that is all I need. Is there a very intelligent way to take existing dates' year field and migrate it to the new IntegerField by altering the method
def forwards(self, orm):
If not, how at all can I change the fieldtype without loosing all data, loosing the stored dates, would be a price i'd pay.
回答1:
One option is to split the task into 3 migrations:
- schema migration: adding
release_year
field - data migration: filling
release_year
field fromrelease_date
field - schema migration: remove
release_date
field and renamerelease_year
torelease_date
Schema migrations would be caught by south automagically (using schemamigration --auto
), but you need to write a data migration manually, here's how your forwards()
method should look like:
def forwards(self, orm):
for source in orm.Source.objects.all():
source.release_year = source.release_date.year
source.save()
Hope that helps.
回答2:
Alecxe's answer really helped me, this is how I implemented this in Django 2.2 as of May 2019:
0042_migration.py
# Generated by Django 2.2 on 2019-05-03 20:35
from django.db import migrations
def forwards(apps, schema_editor):
if schema_editor.connection.alias != 'default':
return
MyModel = apps.get_model('my_app', 'MyModel')
for object in MyModel.objects.all():
object.new_column = object.old_column
object.save()
class Migration(migrations.Migration):
dependencies = [
('my_app', '0041_previous_migration'),
]
operations = [
migrations.RunPython(forwards),
]
来源:https://stackoverflow.com/questions/22413806/south-migrate-datefield-to-integerfield