If Django migration fails due to duplicate keys ...

2016-04-21 | #django, #solution, #webdev

This is an interesting freak error the guys that wrote the migrations let through because they seemingly didn't think migrations through to the last step.

Say you have an error like this:

django.db.utils.InternalError: (1022, u"Can't write; duplicate key in table '#sql-37bd_127'")

How is this possible? Everything is validated beforehand and the DB-specific stuff is handled automatically. The reason this happens is most likely a duplicate name for a foreign key contraint, since those have to be globally unique. But why is that, aren't the constraints hashed with random values on creation? Nope.

What Django does, is to hash the model's name on which a contraint is being created, since table names are unique the contraints must be too, right? Right.

But if you rename a model and migrate that change the migration seemingly does not recreate those constraints. C-bug right? Yes, but in one special case this kills your migration: If you rename a model, migrate that change and after that create another model of the same name with a foreign key the model before also had, the migration will try to create a new contraint with the name the previous migrations didn't redo.

So, that's the case you'll want to avoid. So, after renaming a model, don't create a new model with the same name, with a foreign key to a table the old model had! Solve this in case it already happened by just renaming the new model, the migration fails early enough so that nothing has been touched.