Question

Im working on a Django project using south for schema migrations. I have the following scenario:

schema

class Book(model.Models):
    name = models.CharField(max_length=255, blank=True)
    bid = models.IntegerField(blank=True, null=True)

class Author(model.Models):
   name = models.CharField(max_length=255, blank=True)
   book_id = models.ForeignKey(Book, null=True, to_field="bid", db_column="bookID")

I wanna change Author model to the following:

class Author(model.Models):
   name = models.CharField(max_length=255, blank=True)
   book = models.ForeignKey(Book, null=True, db_column="book_id")

but without loose data. I want to search each book by its bid and assign the one found to the new field in Author model.

Thanks

Was it helpful?

Solution

You'll have to do a 3 migrations. A schemamgiration that adds the new book FK, then a data migration and then a schemamigration to delete and rename the fields.

So you'll want to change your models.py file to this:

class Book(model.Models):
    name = models.CharField(max_length=255, blank=True)
    bid = models.IntegerField(blank=True, null=True)

class Author(model.Models):
   name = models.CharField(max_length=255, blank=True)
   book_id = models.ForeignKey(Book, null=True, to_field="bid", db_column="bookID")
   # You don't need the db_column="book_id" since that's what it does at the DB level by default.
   # I'm not sure if things will break if you name it book with another field as book_id.
   book_new = models.ForeignKey(Book, null=True) 

Then run python manage.py schemamigration APP_NAME auto Then run ```python manage.py datamigration APP_NAME populate_book_id

Then edit the newly created data migration and loop through the Author instances setting the new book field with the book_id field. Don't forget to remove the book field values in the backwards method.

Then change your models.py file to the following:

class Book(model.Models):
    name = models.CharField(max_length=255, blank=True)
    bid = models.IntegerField(blank=True, null=True)

class Author(model.Models):
   name = models.CharField(max_length=255, blank=True)
   # You don't need the db_column="book_id" since that's what it does at the DB level by default.
   book = models.ForeignKey(Book, null=True) 

Then run python manage.py schemamigration APP_NAME auto You'll want to check this last schemamigration to make sure it's renaming book_new to book and not dropping and creating columns. Here's an answer that explains how to change it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top