mirror of https://github.com/django/django.git
Refs #35074 -- Simplified and unified adding spatial indexes on MySQL and Oracle.
This uses `deferred_sql` and `_field_indexes_sql()` instead of custom hooks on MySQL.
This commit is contained in:
parent
b6ad8b687a
commit
e3de574c1e
|
@ -10,10 +10,6 @@ logger = logging.getLogger("django.contrib.gis")
|
|||
class MySQLGISSchemaEditor(DatabaseSchemaEditor):
|
||||
sql_add_spatial_index = "CREATE SPATIAL INDEX %(index)s ON %(table)s(%(column)s)"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.geometry_sql = []
|
||||
|
||||
def skip_default(self, field):
|
||||
# Geometry fields are stored as BLOB/TEXT, for which MySQL < 8.0.13
|
||||
# doesn't support defaults.
|
||||
|
@ -29,29 +25,29 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor):
|
|||
return super().quote_value(str(value))
|
||||
return super().quote_value(value)
|
||||
|
||||
def column_sql(self, model, field, include_default=False):
|
||||
column_sql = super().column_sql(model, field, include_default)
|
||||
# MySQL doesn't support spatial indexes on NULL columns
|
||||
def _field_indexes_sql(self, model, field):
|
||||
if isinstance(field, GeometryField) and field.spatial_index and not field.null:
|
||||
with self.connection.cursor() as cursor:
|
||||
supports_spatial_index = (
|
||||
self.connection.introspection.supports_spatial_index(
|
||||
cursor, model._meta.db_table
|
||||
)
|
||||
)
|
||||
qn = self.connection.ops.quote_name
|
||||
db_table = model._meta.db_table
|
||||
self.geometry_sql.append(
|
||||
self.sql_add_spatial_index
|
||||
% {
|
||||
"index": qn(self._create_spatial_index_name(model, field)),
|
||||
"table": qn(db_table),
|
||||
"column": qn(field.column),
|
||||
}
|
||||
)
|
||||
return column_sql
|
||||
|
||||
def create_model(self, model):
|
||||
super().create_model(model)
|
||||
self.create_spatial_indexes()
|
||||
|
||||
def add_field(self, model, field):
|
||||
super().add_field(model, field)
|
||||
self.create_spatial_indexes()
|
||||
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),
|
||||
}
|
||||
if supports_spatial_index:
|
||||
return [sql]
|
||||
else:
|
||||
logger.error(
|
||||
f"Cannot create SPATIAL INDEX {sql}. Only MyISAM, Aria, and InnoDB "
|
||||
f"support them.",
|
||||
)
|
||||
return []
|
||||
return super()._field_indexes_sql(model, field)
|
||||
|
||||
def remove_field(self, model, field):
|
||||
if isinstance(field, GeometryField) and field.spatial_index and not field.null:
|
||||
|
@ -70,14 +66,3 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor):
|
|||
|
||||
def _create_spatial_index_name(self, model, field):
|
||||
return "%s_%s_id" % (model._meta.db_table, field.column)
|
||||
|
||||
def create_spatial_indexes(self):
|
||||
for sql in self.geometry_sql:
|
||||
try:
|
||||
self.execute(sql)
|
||||
except OperationalError:
|
||||
logger.error(
|
||||
f"Cannot create SPATIAL INDEX {sql}. Only MyISAM, Aria, and InnoDB "
|
||||
f"support them.",
|
||||
)
|
||||
self.geometry_sql = []
|
||||
|
|
|
@ -40,14 +40,27 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor):
|
|||
return super().quote_value(str(value))
|
||||
return super().quote_value(value)
|
||||
|
||||
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 super()._field_indexes_sql(model, field)
|
||||
|
||||
def column_sql(self, model, field, include_default=False):
|
||||
column_sql = super().column_sql(model, field, include_default)
|
||||
if isinstance(field, GeometryField):
|
||||
db_table = model._meta.db_table
|
||||
self.geometry_sql.append(
|
||||
self.sql_add_geometry_metadata
|
||||
% {
|
||||
"table": self.geo_quote_name(db_table),
|
||||
"table": self.geo_quote_name(model._meta.db_table),
|
||||
"column": self.geo_quote_name(field.column),
|
||||
"dim0": field._extent[0],
|
||||
"dim1": field._extent[1],
|
||||
|
@ -57,17 +70,6 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor):
|
|||
"srid": field.srid,
|
||||
}
|
||||
)
|
||||
if field.spatial_index:
|
||||
self.geometry_sql.append(
|
||||
self.sql_add_spatial_index
|
||||
% {
|
||||
"index": self.quote_name(
|
||||
self._create_spatial_index_name(model, field)
|
||||
),
|
||||
"table": self.quote_name(db_table),
|
||||
"column": self.quote_name(field.column),
|
||||
}
|
||||
)
|
||||
return column_sql
|
||||
|
||||
def create_model(self, model):
|
||||
|
|
Loading…
Reference in New Issue