1
0
mirror of https://github.com/django/django.git synced 2024-12-23 01:25:58 +00:00

Refs #35074 -- Added _create_spatial_index_sql()/_delete_spatial_index_sql() hooks to GIS backends.

This commit is contained in:
Mariusz Felisiak 2024-08-18 07:12:51 +02:00 committed by Sarah Boyce
parent d4bce26c94
commit 371a9f3c5f
3 changed files with 54 additions and 43 deletions

View File

@ -33,12 +33,7 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor):
cursor, model._meta.db_table
)
)
qn = self.connection.ops.quote_name
sql = self.sql_add_spatial_index % {
"index": qn(self._create_spatial_index_name(model, field)),
"table": qn(model._meta.db_table),
"column": qn(field.column),
}
sql = self._create_spatial_index_sql(model, field)
if supports_spatial_index:
return [sql]
else:
@ -51,8 +46,7 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor):
def remove_field(self, model, field):
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)
sql = self._delete_spatial_index_sql(model, field)
try:
self.execute(sql)
except OperationalError:
@ -66,3 +60,16 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor):
def _create_spatial_index_name(self, model, field):
return "%s_%s_id" % (model._meta.db_table, field.column)
def _create_spatial_index_sql(self, model, field):
index_name = self._create_spatial_index_name(model, field)
qn = self.connection.ops.quote_name
return self.sql_add_spatial_index % {
"index": qn(index_name),
"table": qn(model._meta.db_table),
"column": qn(field.column),
}
def _delete_spatial_index_sql(self, model, field):
index_name = self._create_spatial_index_name(model, field)
return self._delete_index_sql(model, index_name)

View File

@ -42,16 +42,7 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor):
def _field_indexes_sql(self, model, field):
if isinstance(field, GeometryField) and field.spatial_index:
return [
self.sql_add_spatial_index
% {
"index": self.quote_name(
self._create_spatial_index_name(model, field)
),
"table": self.quote_name(model._meta.db_table),
"column": self.quote_name(field.column),
}
]
return [self._create_spatial_index_sql(model, field)]
return super()._field_indexes_sql(model, field)
def column_sql(self, model, field, include_default=False):
@ -99,8 +90,7 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor):
}
)
if field.spatial_index:
index_name = self._create_spatial_index_name(model, field)
self.execute(self._delete_index_sql(model, index_name))
self.execute(self._delete_spatial_index_sql(model, field))
super().remove_field(model, field)
def run_geometry_sql(self):
@ -114,3 +104,15 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor):
return truncate_name(
"%s_%s_id" % (strip_quotes(model._meta.db_table), field.column), 30
)
def _create_spatial_index_sql(self, model, field):
index_name = self._create_spatial_index_name(model, field)
return self.sql_add_spatial_index % {
"index": self.quote_name(index_name),
"table": self.quote_name(model._meta.db_table),
"column": self.quote_name(field.column),
}
def _delete_spatial_index_sql(self, model, field):
index_name = self._create_spatial_index_name(model, field)
return self._delete_index_sql(model, index_name)

View File

@ -26,29 +26,7 @@ class PostGISSchemaEditor(DatabaseSchemaEditor):
if fields is None or len(fields) != 1 or not hasattr(fields[0], "geodetic"):
return super()._create_index_sql(model, fields=fields, **kwargs)
field = fields[0]
expressions = None
opclasses = None
if field.geom_type == "RASTER":
# For raster fields, wrap index creation SQL statement with ST_ConvexHull.
# Indexes on raster columns are based on the convex hull of the raster.
expressions = Func(Col(None, field), template=self.rast_index_template)
fields = None
elif field.dim > 2 and not field.geography:
# Use "nd" ops which are fast on multidimensional cases
opclasses = [self.geom_index_ops_nd]
name = kwargs.get("name")
if not name:
name = self._create_spatial_index_name(model, field)
return super()._create_index_sql(
model,
fields=fields,
name=name,
using=" USING %s" % self.geom_index_type,
opclasses=opclasses,
expressions=expressions,
)
return self._create_spatial_index_sql(model, fields[0], **kwargs)
def _alter_column_type_sql(
self, table, old_field, new_field, new_type, old_collation, new_collation
@ -82,3 +60,27 @@ class PostGISSchemaEditor(DatabaseSchemaEditor):
def _create_spatial_index_name(self, model, field):
return self._create_index_name(model._meta.db_table, [field.column], "_id")
def _create_spatial_index_sql(self, model, field, **kwargs):
expressions = None
opclasses = None
fields = [field]
if field.geom_type == "RASTER":
# For raster fields, wrap index creation SQL statement with ST_ConvexHull.
# Indexes on raster columns are based on the convex hull of the raster.
expressions = Func(Col(None, field), template=self.rast_index_template)
fields = None
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 (name := kwargs.get("name")):
name = self._create_spatial_index_name(model, field)
return super()._create_index_sql(
model,
fields=fields,
name=name,
using=" USING %s" % self.geom_index_type,
opclasses=opclasses,
expressions=expressions,
)