Influencing order of internal migration operations

22 views
Skip to first unread message

Rich Rauenzahn

unread,
Dec 11, 2019, 12:27:43 PM12/11/19
to Django users
I've created a CompositeForeignKey constraint derived from Django's new BaseConstraint.  It requires that I manually make a unique_together in any of the referenced models views due to the DB internal requirements of composite foreign keys.

It mostly works -- except that when the operations are defined in the migration, the order is critical -- the unique_together's need to be made before the composite key SQL.

For now, I just went in and manually changed the order of operations in the migration to put the CompositeForeignKeys last.   Another way around would be to comment out all the CompositeForeignKey declarations in my models, migrate my unique_together's first, and then re-add the CompositeForeignKeys.

...I'm wondering if there is a supported way to hook into the migration creation process, give priorities to certain kinds of constraints, and then sort the operations by this priority before they are emitted into a migration.py.

Or any other ideas to make this a bit more seamless?

Rich

Simon Charette

unread,
Dec 11, 2019, 1:20:52 PM12/11/19
to Django users
Hello Rich,

Unfortunately the migration framework is not smart enough to resolve this kind of dependency.

The order of operation/migrations of the makemigrations is generated by the autodetector which
hardcodes most of its logic.

I would have assumed that constraints were generated _after_ unique_togethers though[0].

I suspect the operations are ordered this way because the index and constraints operations don't
implement the references_field and references_model operations.

Could you give a try at implementing them for `AddConstraint` based on your CompositeForeignKey
values and see if it helps anyhow?

They should likely be implemented in core but I suspect it will be hard for functional and conditional
indices just like constraints are. I think the best way forward will be to add a `referenced_fields`
property on Index and BaseConstraint that returns a set of (model_label, field_name) tuples and
have index and constraint operations rely on them.

Cheers,
Simon

Reply all
Reply to author
Forward
0 new messages