Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migrate data from one Model to another with Django South

I currently have a structure that needs to be rewritten in order to cope with Django-CMS

Currently the setup is as follows

class Video(models.Model):        
    #embed_code_or_url = models.CharField(max_length=2000)
    permalink = models.URLField(verify_exists=True, unique=True, max_length=255, default="http://", validators=[validate_youtube_address])
    thumbnail = models.CharField(max_length=500, blank=True, null=True)
    # Data
    title = models.CharField(max_length=255, blank=True)
    ...

class VideoPlugin(CMSPlugin):
    video = models.ForeignKey(Video)

when I now transfer all my fields from Video to VideoPlugin, run my schemamigration, I'd also like to transfer ALL the info from Video to VideoPlugin when I run the migration.

Does anyone have an example on how this can be achieved?

Here is the beginnig of the migration to be run

class Migration(SchemaMigration):

    def forwards(self, orm):

        # Adding field 'VideoPlugin.permalink'
        db.add_column('cmsplugin_videoplugin', 'permalink', self.gf('django.db.models.fields.URLField')(default='http://', unique=True, max_length=255), keep_default=False)

        # Adding field 'VideoPlugin.thumbnail'
        db.add_column('cmsplugin_videoplugin', 'thumbnail', self.gf('django.db.models.fields.CharField')(max_length=500, null=True, blank=True), keep_default=False)

        # Adding field 'VideoPlugin.title'
        db.add_column('cmsplugin_videoplugin', 'title', self.gf('django.db.models.fields.CharField')(default='', max_length=255, blank=True), keep_default=False)

        ...

Your help is much appreciated

like image 947
ApPeL Avatar asked Oct 24 '11 14:10

ApPeL


1 Answers

You create a datamigration:

$ python manage.py datamigration yourapp name_of_this_migration

This freezes the models in your app. If another app(s) is/are involved in the migration, you'll need to add --freeze app1 --freeze app2, etc., to that line to include those in your migration as well.

This sets up the basic migration file structure for you, but the forwards and backwards migrations are empty. It's up to your to determine the logic that will migrate data from one to the other. But this works like anything else in Django, except you use the South ORM. For any model in your app in which this migration resides, you use orm.MyModel.objects for any other app that your added with the --freeze parameters, you use orm['someapp.SomeModel'].objects.

Other than that, you just get/filter/create, etc., the objects as normal moving the data from one to the other. Obviously, your forwards migration needs the logic that moves the data where you want it now, and your backwards migration should have the logic required to restore the data to where it was originally.

You can then migrate forwards and backwards in your dev environment to ensure it works properly. One important note: this is only for moving data around. DO NOT alter or delete any table structures in your datamigration. If you need to delete tables after the data has been moved. Create a schemamigration after the datamigration.

like image 147
Chris Pratt Avatar answered Sep 30 '22 04:09

Chris Pratt