Sometimes, old design decisions comes back to bite you. This is one of those tales.
A project I’m working on had a Django model similar to this:
class Municipality(models.Model):
code = models.CharField(max_length=2, primary_key=True)
name = models.CharField(max_length=100)
and it was used by other models such as:
class ZipCode(models.Model):
code = models.CharField(max_length=4, primary_key=True)
municipality = models.ForeignKey(Municipality)
And all was good, until we needed to expand the municipality model to support different countries, and thus a single unique field with only the code
- which may collide across countries, was not enough.
For all the modern parts of the code base we use UUID
s as the primary key,
so we wanted to migrate the primary key of Municipality
to a UUID
, while
retaining all the relations.
As of September 2017, Django does not support migrating primary keys in any nice manner, so we’re on our own here.
We tried a lot of magic solutions, but we always got stuck with the migrations system not being able to detect and handle the changes nicely.
After some research and quite a bit of trial and error, we settled on the following approach. It has some drawbacks I’ll get back to, but works reasonable well.
Read more...