How to move data migration from one-to-one move to a pair

I am using South to manage the migration, and I have reached a corner. Basically I have the following settings:

Application 1:

< p>

class A(models.Model):
# bunch of attributes

Application 2:

class B(models.Models):
instance_a = models.OneToOneField(A, null=True, blank=True,
editable=False)

Now, I want to go from here to this:

Application 1:

class A(models.Model):
instance_b = models.ForeignKey(B, null=True, blank= True)

Application 2:

class B(models.Models):
# other attributes

My The main problem is that I cannot lose data. So basically at the end of the migration, all object A previously mapped to object B should keep that mapping. For example, if object A with id 7 is mapped to object B with id 8, The mapping should be retained at the end of the process.

I tried some pattern migrations mixed with temporary placeholders and data migration. But I always end up in the same place, which is executing data When migrating, I no longer have the previous relationship in order to access the correct attributes. For example, B.instance_a is no longer available.

I hope you understand two things:

> First of all, is it possible to use only southern migration.
>Second, what should I do.

Thank you

Finally, after a while, I got a django-south program that can help others. The key is the depends_on function in South (http://south.aeracode.org/wiki/Dependenci es). I completed it in four steps:

First:

>Create a placeholder for the foreign key value in model A.

So model A becomes:

class A(models.Model):
instance_b_placeholder = models.ForeignKey(A, null=True, blank=True)

pre>

Now run manage.py schemamigration app1 --auto.

Second

>Create a data migration so that we can copy the values. The goal is to copy the data to the database , Rename the attributes later and delete the old attributes. Issue manage.py datamigration app1 update_fields. I chose to keep the data migration in app1. If you don’t, make sure it runs after the last migration.

This is the data migration code:

# Forwards:

for b in orm['app2.B'].objects.filter(instance_b__isnull= False):
b.instance_a.instance_b_placeholder = b
b.instance_a.save()

# Backwards:

for r in orm[' app1.A'].objects.filter(instance_b_placeholder__isnull=False):
r.instance_b_placeholder.instance_a = r
r.instance_b_placeholder.save()

Third:

>Remove the field instance_b from Model B, and make sure to run the migration after the migration created in the previous step.

Model B becomes:

< pre>class B(models.Model):
# etc...

Issue manage.py schemamigration app2 –aut o And edit the migration, add the previous migration to depends_on:

depends_on = (
("app1", "_update_fields"),
)

Step 4:

>Rename the placeholder. This is achieved by changing the name in the code and editing migration. Editing is necessary because of the southern tendency I deleted and added a new column, but we only want it to rename the column.
>This migration should run in the last position, so I rely on the previous migration.

This is the code:< /p>

depends_on = (
("app2", ""),
)

# Forwards:

db.rename_column('app1_a','instance_b_placeholder_id','instance_b_id')

# Backwards:

db.rename_column('app1_a', ' instance_b_id','instance_b_placeholder_id')

That’s it. I don’t know if there are many other ways to do this, but at least it helps me.

< /p>

I am using South to manage the migration, and I have reached a corner. Basically I have the following settings:

Application 1:

class A(models.Model):
# bunch of attributes

Application 2:

class B(models.Models ):
instance_a = models.OneToOneField(A, null=True, blank=True,
editable=False)

Now, I want to go from here to this:

< p>Application 1:

class A(models. Model):
instance_b = models.ForeignKey(B, null=True, blank=True)

Application 2:

class B( models.Models):
# other attributes

My main problem is that I cannot lose data. Therefore, basically at the end of the migration, all object A previously mapped to object B should remain that Mapping. For example, if object A with id 7 is mapped to object B with id 8, that mapping should be retained at the end of the process.

I tried something with temporary placeholders and data Migrating a mixed mode migration. But I always end up in the same place, which is when performing data migration I no longer have the previous relationship in order to access the correct attributes. For example, B.instance_a is no longer available.

< p>I hope you have some understanding of two things:

>Firstly, is it possible to use only southern migration.
>Secondly, what should I do.

Thank you

Finally, after a while, I got a django-south program that can help others. The key is the depends_on function of South (http:// south.aeracode.org/wiki/Dependencies). I did it in four steps:

First:

>Create a placeholder for the foreign key value in model A .

So model A becomes:

class A(models.Model):
instance_b_placeholder = models.ForeignKey(A, null= True, blank=True)

Now run manage.py schemamigration app1 –auto.

Second

>Create a data migration so that we can copy the values. The goal is to copy the data into the database, rename the attributes later and delete the old attributes. Issue manage.py datamigration app1 update_fields. I choose to keep the data migration in app1. If you don’t, make sure it is after the last migration Run.

This is the data migration code:

# Forwards:

for b in orm['app2. B'].objects.filter(instance_b__isnull=False):
b.instance_a.instance_b_placeholder = b
b.instance_a.save()

# Backwards:

for r in orm['app1.A'].objects.filter(instance_b_placeholder__isnull=False):
r.instance_b_placeholder.instance_a = r
r.instance_b_placeholder.save()

Third:

>Delete the field instance_b from model B, and make sure to run the migration after the migration created in the previous step.

Model B becomes:

p>

class B(models.Model):
# etc...

Issue manage.py schemamigration app2 –auto and edit the migration, change the previous Add the migration to depends_on:

depends_on = (
("app1", "_update_fields"),
)

< p>Step 4:

>Rename the placeholder. This is achieved by changing the name in the code and editing the migration. Editing is necessary because the South tends to delete and add new columns, But we only want it to rename the column.
>This migration should run in the last position, so I rely on the previous migration.

This is the code:

< /p>

depends_on = (
("app2", ""),
)

# Forwards:

db .rename_column('app1_a','instance_b_placeholder_id','instance_b_id')

# Backwards:
db.rename_column('app1_a','instance_b_id','instance_b_placeholder_id')

That’s it. I don’t know if there are many other ways to do this, but At least it helps me.

Leave a Comment

Your email address will not be published.