Reputation: 185
Im working on a Django project using south for schema migrations. I have the following scenario:
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
Upvotes: 6
Views: 2469
Reputation: 13731
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.
Upvotes: 5