0

So I have the given model:

class FooBar(models.Model):
    foo = models.ForeignKey(Foo,null=True,blank=True)
    bar = models.ForeignKey(Bar,null=True,blank=True)
    foo_flag = models.BooleanField(default=False)
    bar_flag = models.BooleanField(default=False)

where the logic was that at all times, there can either be a foreign key to Foo or Bar and not both.But now the logic has changed so that there is always a Foo foreign key and sometimes a Bar. So my new model looks as such:

class FooBar(models.Model):
    foo = models.ForeignKey(Foo)
    bar = models.ForeignKey(Bar,null=True,blank=True)
    bar_flag = models.BooleanField(default=False)

Now here is the complex part. The Bar model looks as such:

class Bar(models.Model):
    foo = models.ForeignKey(Foo)

so for every previously existing item in the database where the foo field is null and therefore there is a foreign key to Bar, I need the foo field to get a foreign key to the same Foo object that has the bar fields object has a foreign key to. Here is the logic stepped out:

  1. delete FooBar.foo_flag
  2. populate all null foo foreign keys with the Foo objects from the Bar foreign keys
  3. no longer allow null in foo field

How could I go about writing this migration?

Ryan Saxe
  • 17,123
  • 23
  • 80
  • 128

1 Answers1

2

Best practices for situations like that is make 3 independent migrations:

  1. Data migration, where you iterate over all FooBar items and populate proper values.
  2. Schema migration, where you set NOT NULL constraint to your ForeignKeys. South will request "default" value for unpopulated items. In most cases you should not have that items, but if something go wrong, you need easily detectable value, so you shoud make fake Foo item and set it's id as default.
  3. Schema migration, where you delete FooBar.foo_flag

After migration, I recommend check tables for fake Foo object links and fix data manually if something go wrong.

oxyum
  • 6,387
  • 1
  • 15
  • 13
  • in doing what you want, I cannot seem to write the data migration that updates. I posted here if you know how to do this: http://stackoverflow.com/questions/21439031/django-f-expressions-joined-field – Ryan Saxe Jan 29 '14 at 18:03