I’m using south to manage migrations and I’ve hit a corner. Basically I have the following setup:
App1:
class A(models.Model):
# bunch of attributes
App2:
class B(models.Models):
instance_a = models.OneToOneField(A, null=True, blank=True,
editable=False)
Now, I want to go from this to this:
App1:
class A(models.Model):
instance_b = models.ForeignKey(B, null=True, blank=True)
App2:
class B(models.Models):
# other attributes
My main issue is that I can’t loose data. So basically at the end of the migration(s) all objects A that mapped previously to objects B should keep that mapping. As an example, if object A with id 7 was mapped to object B with id 8, by the end of this procedure this mapping should be retained.
I tried several things from schema migrations mixed with temporary place holders and data migrations. However I end up always in the same place, which is by the time the data migration is performed I no longer have the previous relations in order to access the correct attributes. So for example, B.instance_a is no longer available.
I would like your opinion on two things:
- First, is this viable at all using just south migrations.
- Second, how shall I proceed.
Thanks
Finally after some time I got a procedure with
django-souththat might help others. The key was in south’sdepends_onfeature (http://south.aeracode.org/wiki/Dependencies). I did it in 4 steps:First:
A.So model
Abecomes:Now just run
manage.py schemamigration app1 --auto.Second
manage.py datamigration app1 update_fields. I chose to keep the datamigration inapp1. If you don’t do this just make sure it runs after the previous migration.Here’s the datamigration coded:
Third:
instance_bfrom modelBand be sure to make the migration run after the one created in the previous step.Model
Bbecomes:Issue
manage.py schemamigration app2 --autoand edit the migration adding the previous migration todepends_on:Forth step:
Rename the place holder. This is achieved by changing the name in the code and editing the migration. Editing is necessary because
southtends to delete and add a new column, but we only want it to rename the column.This migration should run in last place, so I made it dependent on the previous one.
Here’s the code:
So that’s it. I don’t know if there are so many other ways to do it, but at least this helped me.