Ryan Saxe
Ryan Saxe

Reputation: 17859

Django south migration foreign key

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?

Upvotes: 0

Views: 1592

Answers (1)

oxyum
oxyum

Reputation: 6787

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.

Upvotes: 2

Related Questions