diff options
author | Sergey Fursov <geyser85@gmail.com> | 2021-12-29 00:18:17 +0300 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-09-13 10:38:57 +0200 |
commit | b731e8841558ee4caaba766c83f34ea9c7004f8b (patch) | |
tree | feb5596cfa8c5397ad3172f19c2985ecb4c41d19 /django/db/backends/mysql/schema.py | |
parent | 1b08e9bf7d88dbad9324f462e5fc7ec582aef3cc (diff) | |
download | django-b731e8841558ee4caaba766c83f34ea9c7004f8b.tar.gz |
Fixed #31335 -- Fixed removing composed composed Meta constraints/indexes on foreign keys on MySQL.
Diffstat (limited to 'django/db/backends/mysql/schema.py')
-rw-r--r-- | django/db/backends/mysql/schema.py | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/django/db/backends/mysql/schema.py b/django/db/backends/mysql/schema.py index 044a752c7a..821f4ddbce 100644 --- a/django/db/backends/mysql/schema.py +++ b/django/db/backends/mysql/schema.py @@ -1,5 +1,6 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor -from django.db.models import NOT_PROVIDED +from django.db.models import NOT_PROVIDED, F, UniqueConstraint +from django.db.models.constants import LOOKUP_SEP class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): @@ -117,6 +118,23 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): [effective_default], ) + def remove_constraint(self, model, constraint): + if isinstance(constraint, UniqueConstraint): + self._create_missing_fk_index( + model, + fields=constraint.fields, + expressions=constraint.expressions, + ) + super().remove_constraint(model, constraint) + + def remove_index(self, model, index): + self._create_missing_fk_index( + model, + fields=[field_name for field_name, _ in index.fields_orders], + expressions=index.expressions, + ) + super().remove_index(model, index) + def _field_should_be_indexed(self, model, field): if not super()._field_should_be_indexed(model, field): return False @@ -140,6 +158,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): model, *, fields, + expressions=None, ): """ MySQL can remove an implicit FK index on a field when that field is @@ -150,14 +169,36 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): Manually create an implicit FK index to make it possible to remove the composed index. """ - first_field = model._meta.get_field(fields[0]) + first_field_name = None + if fields: + first_field_name = fields[0] + elif ( + expressions + and self.connection.features.supports_expression_indexes + and isinstance(expressions[0], F) + and LOOKUP_SEP not in expressions[0].name + ): + first_field_name = expressions[0].name + + if not first_field_name: + return + + first_field = model._meta.get_field(first_field_name) if first_field.get_internal_type() == "ForeignKey": - constraint_names = self._constraint_names( - model, - [first_field.column], - index=True, + column = self.connection.introspection.identifier_converter( + first_field.column ) - if not constraint_names: + with self.connection.cursor() as cursor: + constraint_names = [ + name + for name, infodict in self.connection.introspection.get_constraints( + cursor, model._meta.db_table + ).items() + if infodict["index"] and infodict["columns"][0] == column + ] + # There are no other indexes that starts with the FK field, only + # the index that is expected to be deleted. + if len(constraint_names) == 1: self.execute( self._create_index_sql(model, fields=[first_field], suffix="") ) |