Ticket #434 (assigned defect)

Opened 6 years ago

Last modified 5 years ago

Ordering of items in a Migration leads to error

Reported by: leovitch Owned by: andrew
Priority: major Milestone: 1.0
Component: migrations Version: 0.7
Keywords: Cc:


I generated a schema migration which contained the following lines:

class Migration(SchemaMigration):
    def forwards(self, orm):
        # Deleting field 'Asset.type'
        db.delete_column('assetversions_asset', 'type_id')

        # Changing field 'Asset.category'
        db.alter_column('assetversions_asset', 'category_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['AssetVersions.AssetCategory']))

        # Removing unique constraint on 'Asset', fields ['project', 'type', 'name']
        db.delete_unique('assetversions_asset', ['project_id', 'type_id', 'name'])

        # Adding unique constraint on 'Asset', fields ['project', 'category', 'name']
        db.create_unique('assetversions_asset', ['project_id', 'category_id', 'name'])

Not surprisingly this fails when executed, since the constraint on the Asset.type field isn't deleted (in the third command) until after the column itself is deleted (in the first command). I'm using MySQL (and yes I know it doesn't have transaction support for schema changes) but it sure seems reasonable that any database would be upset about deleting a column before deleting a constraint on that column.

Is it feasible to change south to always generate deletions of constraints first within a migration?

The context (not sure if it matters or not but just to be clear) is that I'm doing a three-step schema-data-schema migration. Asset used to have a ForeignKey? on AssetType?, but now it has a ForeignKey? on AssetCategory? which links to on AssetType?. This error happens in the third step when I'm cleaning up the old AssetType? link and the unique_together constraint that goes with it. I also ran into the already-fixed bug in ticket #403 because of my data migration wasn't bug-free on the first try ;-). Thanks for the fix on that!

Obviously, I can (and did) work around this easily once I found it. I edited the migration file and put the delete of the old constraint first in the forwards() method. So in that sense, it's not a critical problem. But it is exactly the sort of thing I want the migrations layer to handle for me so I don't have to think about it every time!


P.S. And to be clear even though I'm filing a ticket... south is awesome and I really appreciate it! This is my first south project so apologies for not knowing the code well enough to suggest a patch.


south-adjust_ordering.diff (10.4 KB) - added by ogier 5 years ago.
A patch that solves ordering issues I encountered with MySQL

Change History

comment:1 Changed 6 years ago by andrew

  • Status changed from new to assigned
  • Milestone set to 1.0

Yes, this isn't a critical bug - it can easily be fixed manually - but the migration generator really should be doing it in the right order. I'll schedule it in for the 1.0 release.

Also, don't worry about not filing a patch too; a bug report is a good start! For future reference, you can put your email address in the "reporter" field, and you'll get emailed with ticket updates (and Trac will hide the domain part of the address from anyone without a login)

Changed 5 years ago by ogier

A patch that solves ordering issues I encountered with MySQL

comment:2 Changed 5 years ago by ogier

I added a patch that solved this issue for me. It sort of clobbered the auto generated names for migrations since the first thing that happens in the absence of an added or removed model is the deletion of unique_together constraints. However, it makes up for that by correctly unwinding all constraints to be removed, adjusting all fields, then putting on all new constraints. It also reverses the order of the generated actions in backwards() to undo actions in a LIFO style.

comment:3 Changed 5 years ago by andrew

Hm, LIFO is not necessarily correct (old South used to do that, and unfortunately there were a few edge cases). Still, I'll have a look at the patch in a week or so when I get time.

Note: See TracTickets for help on using tickets.