summaryrefslogtreecommitdiff
path: root/django/db/backends/mysql/schema.py
diff options
context:
space:
mode:
authorSergey Fursov <geyser85@gmail.com>2021-12-29 00:18:17 +0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-09-13 10:38:57 +0200
commitb731e8841558ee4caaba766c83f34ea9c7004f8b (patch)
treefeb5596cfa8c5397ad3172f19c2985ecb4c41d19 /django/db/backends/mysql/schema.py
parent1b08e9bf7d88dbad9324f462e5fc7ec582aef3cc (diff)
downloaddjango-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.py55
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="")
)