Opened 7 years ago

Closed 5 years ago

#29097 closed Bug (fixed)

Migrations using MySQL fail for constraints using composite indexes

Reported by: geertjanvdk Owned by: Hasan Ramezani
Component: Migrations Version: 1.11
Severity: Normal Keywords: introspection mysql migration index constraint
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When running migrations which create (unique) composite indexes, the MySQL introspection fails to get the correct index:

ValueError: Found wrong number (0) of constraints for product_versions(product_id, ordering)

This was previously reported as fixed (see https://code.djangoproject.com/ticket/28697), but it is not. Using 1.11.5, and 1.11.9, it fails.

The fix is very easy: in DatabaseIntrospection.get_constraints(), an ORDER BY is missing when selecting from the table INFOMRATION_SCHEMA.KEY_COLUMN_USAGE:

Thus:

    def get_constraints(self, cursor, table_name):
        """
        Retrieves any constraints or keys (unique, pk, fk, check, index) across one or more columns.
        """
        constraints = {}
        # Get the actual constraint names and columns
        name_query = """
            SELECT kc.`constraint_name`, kc.`column_name`,
                kc.`referenced_table_name`, kc.`referenced_column_name`
            FROM information_schema.key_column_usage AS kc
            WHERE
                kc.table_schema = DATABASE() AND
                kc.table_name = %s
            ORDER BY kc.`constraint_name`, kc.`ordinal_position`
        """
       ....

The ORDER BY assures the order the columns were specified. the SHOW INDEX statement does this by default.

The above should work for all MySQL versions supported.

Note that Django 2.0 has the same issue.

Patch available https://github.com/geertjanvdk/django/commit/ab0bcb327c51aab71f58789eb55a7981dcb06fdb

Change History (6)

comment:1 by Basu Dubey, 7 years ago

Owner: changed from nobody to Basu Dubey
Status: newassigned

comment:2 by Tim Graham, 7 years ago

Easy pickings: unset
Needs tests: set
Triage Stage: UnreviewedAccepted

comment:3 by Basu Dubey, 7 years ago

Owner: Basu Dubey removed
Status: assignednew

comment:4 by Simon Charette, 5 years ago

Component: Database layer (models, ORM)Migrations

comment:5 by Hasan Ramezani, 5 years ago

Needs tests: unset
Owner: set to Hasan Ramezani
Status: newassigned

Seems it has been fixed in https://github.com/django/django/commit/4fba321a457e52df77d0b512d043019e9f6b0bc9
I Added a patch to test it.

Question: Do we need to add kc.'constraint_name' to ORDER BY as well?

comment:6 by Mariusz Felisiak, 5 years ago

Resolution: fixed
Status: assignedclosed

kc.'constraint_name' in an ORDER BY should not be necessary. I think we can close this issue because ordering was added in 4fba321a457e52df77d0b512d043019e9f6b0bc9 and creating a regression test may not be feasible (see discussion).

Note: See TracTickets for help on using tickets.
Back to Top