From 29345aecf6e8d53ccb3577a3762bb0c263f7558d Mon Sep 17 00:00:00 2001 From: snowman2 Date: Thu, 13 May 2021 13:02:31 +0200 Subject: [PATCH] Fixed #32721 -- Fixed migrations crash when adding namespaced spatial indexes on PostGIS. --- .../contrib/gis/db/backends/postgis/schema.py | 7 +++-- tests/gis_tests/geoapp/test_indexes.py | 26 +++++++++++++++++++ .../gis_migrations/test_operations.py | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/django/contrib/gis/db/backends/postgis/schema.py b/django/contrib/gis/db/backends/postgis/schema.py index a4b4910c36..c574bed84f 100644 --- a/django/contrib/gis/db/backends/postgis/schema.py +++ b/django/contrib/gis/db/backends/postgis/schema.py @@ -33,10 +33,9 @@ class PostGISSchemaEditor(DatabaseSchemaEditor): elif field.dim > 2 and not field.geography: # Use "nd" ops which are fast on multidimensional cases opclasses = [self.geom_index_ops_nd] - if not kwargs.get('name'): - name = '%s_%s_id' % (model._meta.db_table, field.column) - else: - name = kwargs['name'] + name = kwargs.get('name') + if not name: + name = self._create_index_name(model._meta.db_table, [field.column], '_id') return super()._create_index_sql( model, diff --git a/tests/gis_tests/geoapp/test_indexes.py b/tests/gis_tests/geoapp/test_indexes.py index 4aee5062d8..ce9376d810 100644 --- a/tests/gis_tests/geoapp/test_indexes.py +++ b/tests/gis_tests/geoapp/test_indexes.py @@ -1,6 +1,8 @@ +from django.contrib.gis.db import models from django.db import connection from django.db.models import Index from django.test import TransactionTestCase +from django.test.utils import isolate_apps from .models import City @@ -38,6 +40,30 @@ class SchemaIndexesTests(TransactionTestCase): str(index.create_sql(City, editor)), ) + @isolate_apps('gis_tests.geoapp') + def test_namespaced_db_table(self): + if not connection.ops.postgis: + self.skipTest('PostGIS-specific test.') + + class SchemaCity(models.Model): + point = models.PointField() + + class Meta: + app_label = 'geoapp' + db_table = 'django_schema"."geoapp_schema_city' + + index = Index(fields=['point']) + editor = connection.schema_editor() + create_index_sql = str(index.create_sql(SchemaCity, editor)) + self.assertIn( + '%s USING ' % editor.quote_name(SchemaCity._meta.db_table), + create_index_sql, + ) + self.assertIn( + 'CREATE INDEX "geoapp_schema_city_point_9ed70651_id" ', + create_index_sql, + ) + def test_index_name(self): if not self.has_spatial_indexes(City._meta.db_table): self.skipTest('Spatial indexes in Meta.indexes are not supported.') diff --git a/tests/gis_tests/gis_migrations/test_operations.py b/tests/gis_tests/gis_migrations/test_operations.py index 25d55619ed..6c7adcf359 100644 --- a/tests/gis_tests/gis_migrations/test_operations.py +++ b/tests/gis_tests/gis_migrations/test_operations.py @@ -210,7 +210,7 @@ class OperationTests(OperationTestCase): self.assertSpatialIndexExists('gis_neighborhood', 'point3d') with connection.cursor() as cursor: - index_name = 'gis_neighborhood_point3d_id' + index_name = 'gis_neighborhood_point3d_113bc868_id' cursor.execute(self.get_opclass_query, [index_name]) self.assertEqual( cursor.fetchall(),