Skip to content

Commit 37ffeb4

Browse files
committed
create spatial indexes on embedded GIS fields
1 parent 3bd4c5f commit 37ffeb4

File tree

3 files changed

+52
-9
lines changed

3 files changed

+52
-9
lines changed

django_mongodb_backend/gis/schema.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ def _field_should_be_indexed(self, model, field):
99
return super()._field_should_be_indexed(model, field)
1010

1111
def _add_field_index(self, model, field, *, column_prefix=""):
12-
if hasattr(field, "geodetic"):
13-
self._add_spatial_index(model, field)
12+
if getattr(field, "spatial_index", False):
13+
self._add_spatial_index(model, field, column_prefix)
1414
else:
1515
super()._add_field_index(model, field, column_prefix=column_prefix)
1616

@@ -42,15 +42,15 @@ def _alter_field(
4242
elif old_field_spatial_index and not new_field_spatial_index:
4343
self._delete_spatial_index(model, new_field)
4444

45-
def _add_spatial_index(self, model, field):
46-
index_name = self._create_spatial_index_name(model, field)
45+
def _add_spatial_index(self, model, field, column_prefix=""):
46+
index_name = self._create_spatial_index_name(model, field, column_prefix)
4747
self.get_collection(model._meta.db_table).create_indexes(
48-
[IndexModel([(field.column, GEOSPHERE)], name=index_name)]
48+
[IndexModel([(column_prefix + field.column, GEOSPHERE)], name=index_name)]
4949
)
5050

5151
def _delete_spatial_index(self, model, field):
5252
index_name = self._create_spatial_index_name(model, field)
5353
self.get_collection(model._meta.db_table).drop_index(index_name)
5454

55-
def _create_spatial_index_name(self, model, field):
56-
return f"{model._meta.db_table}_{field.column}_id"
55+
def _create_spatial_index_name(self, model, field, column_prefix=""):
56+
return f"{model._meta.db_table}_{column_prefix}{field.column}_id"

django_mongodb_backend/schema.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def wrapper(self, model, *args, **kwargs):
2828
return wrapper
2929

3030

31-
class DatabaseSchemaEditor(GISSchemaEditor, BaseDatabaseSchemaEditor):
31+
class BaseSchemaEditor(BaseDatabaseSchemaEditor):
3232
def get_collection(self, name):
3333
if self.collect_sql:
3434
return OperationCollector(self.collected_sql, collection=self.connection.database[name])
@@ -419,3 +419,8 @@ def _field_should_have_unique(self, field):
419419
db_type = field.db_type(self.connection)
420420
# The _id column is automatically unique.
421421
return db_type and field.unique and field.column != "_id"
422+
423+
424+
# GISSchemaEditor extends some SchemaEditor methods.
425+
class DatabaseSchemaEditor(GISSchemaEditor, BaseSchemaEditor):
426+
pass

tests/schema_/test_embedded_model.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import itertools
22

33
from django.db import connection, models
4-
from django.test import TransactionTestCase
4+
from django.test import TransactionTestCase, skipUnlessDBFeature
55
from django.test.utils import isolate_apps
66

77
from django_mongodb_backend.fields import EmbeddedModelField
@@ -552,3 +552,41 @@ def test_embedded_alter_field_ignored(self):
552552
new_field.set_attributes_from_name("new")
553553
with connection.schema_editor() as editor, self.assertNumQueries(0):
554554
editor.alter_field(Author, old_field, new_field)
555+
556+
557+
@skipUnlessDBFeature("gis_enabled")
558+
class GISTests(TestMixin, TransactionTestCase):
559+
@isolate_apps("schema_")
560+
def test_create_model(self):
561+
"""
562+
Spatial indexes for embedded GIS fields are created when the collections are
563+
created.
564+
"""
565+
from django.contrib.gis.db.models import PointField
566+
567+
class Place(EmbeddedModel):
568+
name = models.CharField(max_length=10)
569+
location = PointField()
570+
571+
class Meta:
572+
app_label = "schema_"
573+
574+
class Author(models.Model):
575+
birthplace = EmbeddedModelField(Place)
576+
577+
class Meta:
578+
app_label = "schema_"
579+
580+
with connection.schema_editor() as editor:
581+
# Create the table
582+
editor.create_model(Author)
583+
self.assertTableExists(Author)
584+
# The embedded GEO indexes is created.
585+
constraint_name = "schema__author_birthplace.location_id"
586+
self.assertEqual(
587+
self.get_constraints_for_columns(Author, ["birthplace.location"]),
588+
[constraint_name],
589+
)
590+
self.assertIndexOrder(Author._meta.db_table, constraint_name, ["GEO"])
591+
editor.delete_model(Author)
592+
self.assertTableNotExists(Author)

0 commit comments

Comments
 (0)