Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I combine schema and data (South) migrations into one?

Tags:

django-south

I want to move the field honk and it's data from one model to another using South:

class Foo(models.Model):
    foofield = models.CharField()
    honk = models.PositiveIntegerField()

class Bar(models.Model):
    barfield = models.CharField()

I've done this before, using 3 separate migrations:

  1. A schema migration, adding honk to Bar
  2. A data migration, copying all Foo.honk data to Bar.honk
  3. Another schema migration, dropping honk from Foo

Can I do these three steps in a single migration?

I've already learnt that there isn't much of a difference between schema and data migrations in South, so I figured perhaps something like this might work (which is the three migrations above just munged into one):

class Migration(DataMigration):
    def forwards(self, orm):
        # add column
        db.add_column('myapp_bar', 'honk', self.gf('django.db.models.fields.PositiveIntegerField')(default='0'), keep_default=False)

        # copy data
        for foo in Foo.objects.all():
            # find the right bar here and then ...
            bar.honk = foo.honk
            bar.save()

        # remove old column
        db.delete_column('myapp_foo', 'honk')

Will this work or will it fail because my (South frozen) orm doesn't know about Bar.honk yet? Or am I doing it wrong and there's a nicer way to do this sort of thing in a single migration?

like image 371
Ingmar Hupp Avatar asked Jan 06 '12 10:01

Ingmar Hupp


People also ask

How do I merge two migrations in Django?

execute python manage.py makemigrations –merge and the migrations will automatically be merged; you will see that a new migration, 0004_merge.py, is created inside the migrations folder. execute python manage.py migrate.

What is the difference between makemigrations and migrate?

migrate , which is responsible for applying and unapplying migrations. makemigrations , which is responsible for creating new migrations based on the changes you have made to your models.

How do you schema migration?

Migrations are performed programmatically by using a schema migration tool. When invoked with a specified desired schema version, the tool automates the successive application or reversal of an appropriate sequence of schema changes until it is brought to the desired state.

What is the use of makemigrations in Django?

makemigrations : It is used to create a migration file that contains code for the tabled schema of a model. migrate : It creates table according to the schema defined in the migration file.


1 Answers

Since this question earned me a Tumbleweed badge, I've dug in and tried it myself. Here's what I've found out.

No you can't merge these migrations

Because the ORM freeze only contains the schema you are migrating to. So in the above example, foo.honk wouldn't be accessible during the data migration (the for loop), because it is deleted during the schema migration, so it isn't in the frozen ORM. Additionally you'll get DatabaseError exceptions if you try to access data because the columns in the database don't yet match the ones of the model (i.e. if you try to access anything before a db.add_column).

Looks like there's no simple shortcut and doing something like this does take the 3 migrations mentioned above.

like image 199
Ingmar Hupp Avatar answered Sep 22 '22 11:09

Ingmar Hupp