From 20c2d625d3d5062e43918d1d7b6f623202491dd4 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Tue, 18 Jun 2024 22:19:11 +0200 Subject: [PATCH] Refs #35074 -- Avoided failed attempts to remove spatial indexes on nullable fields on MySQL. MySQL doesn't support spatial indexes on NULL columns, so there is no point in removing them. --- django/contrib/gis/db/backends/mysql/schema.py | 2 +- .../gis_migrations/test_operations.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/django/contrib/gis/db/backends/mysql/schema.py b/django/contrib/gis/db/backends/mysql/schema.py index 27f6df174a..f3ddf14fa7 100644 --- a/django/contrib/gis/db/backends/mysql/schema.py +++ b/django/contrib/gis/db/backends/mysql/schema.py @@ -54,7 +54,7 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor): self.create_spatial_indexes() def remove_field(self, model, field): - if isinstance(field, GeometryField) and field.spatial_index: + if isinstance(field, GeometryField) and field.spatial_index and not field.null: index_name = self._create_spatial_index_name(model, field) sql = self._delete_index_sql(model, index_name) try: diff --git a/tests/gis_tests/gis_migrations/test_operations.py b/tests/gis_tests/gis_migrations/test_operations.py index 033f2ac5b9..3ecde2025e 100644 --- a/tests/gis_tests/gis_migrations/test_operations.py +++ b/tests/gis_tests/gis_migrations/test_operations.py @@ -133,6 +133,24 @@ class OperationTests(OperationTestCase): if self.has_spatial_indexes: self.assertSpatialIndexExists("gis_neighborhood", "path") + @skipUnless(connection.vendor == "mysql", "MySQL specific test") + def test_remove_geom_field_nullable_with_index(self): + # MySQL doesn't support spatial indexes on NULL columns. + with self.assertNumQueries(1) as ctx: + self.alter_gis_model( + migrations.AddField, + "Neighborhood", + "path", + fields.LineStringField, + field_class_kwargs={"null": True}, + ) + self.assertColumnExists("gis_neighborhood", "path") + self.assertNotIn("CREATE SPATIAL INDEX", ctx.captured_queries[0]["sql"]) + + with self.assertNumQueries(1), self.assertNoLogs("django.contrib.gis", "ERROR"): + self.alter_gis_model(migrations.RemoveField, "Neighborhood", "path") + self.assertColumnNotExists("gis_neighborhood", "path") + @skipUnless(HAS_GEOMETRY_COLUMNS, "Backend doesn't support GeometryColumns.") def test_geom_col_name(self): self.assertEqual(