Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using South to convert ForeignKey TO ManyToManyField not working out

I am using South to change a ForeignKey TO ManyToManyField in one of the models in Django but it is not working out as expected.

# Original Schema
class Item(models.Model):
    category = models.ForeignKey(Category, default=default_category)

To be changed to

# Original Schema
class Item(models.Model):
    category = models.ManyToManyField(Category, default=default_category)

So after commenting out the ForeignKey line in the model I do,

python manage.py schemamigration affected_model --auto
 ? The field 'Item.category' does not have a default specified, yet is NOT NULL.
 ? Since you are removing this field, you MUST specify a default
 ? value to use for existing rows. Would you like to:
 ?  1. Quit now, and add a default to the field in models.py
 ?  2. Specify a one-off value to use for existing columns now
 ?  3. Disable the backwards migration by raising an exception.
 ? Please select a choice: 

I am confused by this because 1. I have specified a default value which is "default_category" and 2. I am not removing any field I am just changing it to ManyToManyField. My question is how to go ahead in this case? Is there any other trick to make this conversion using South?

BTW I am using South 0.7 and Django 1.1.1

Thanks for the help.

like image 444
Chantz Avatar asked Jun 28 '11 16:06

Chantz


1 Answers

In fact you are removing the field. Foreignkeys are represented by a column in your database that in that case would be named category_id. ManyToMany relationships are represented by a "through" table. With django you can either specif the through table or have one generated for you automatically.

This is a very nontrivial migration and you will need to hand code it. It will require a bit of understanding what the underlying database representation of your model is.

You will require 3 migrations to cleanly do this. First create a schemamigration with a dummy manytomany relationship to hold your data.

Then create a datamigration to copy the foreignkey relationships to your dummy manytomany

Finally create schemamigration to delete the foreignkey and rename the dummy manytomany table.

Steps 2 and 3 will both require you to manually write the migrations. I should emphasize this is a very nontrivial style of migration. However, it's entirely doable you just have to really understand what these relationships mean to the database more than your average migration. If you have little or no data it would be much simpler to just drop the tables and start over fresh with your migrations.

like image 106
John Avatar answered Oct 15 '22 11:10

John