You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

schema.py 3.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from django.contrib.gis.db.models.fields import GeometryField
  2. from django.db.backends.oracle.schema import DatabaseSchemaEditor
  3. from django.db.backends.utils import strip_quotes, truncate_name
  4. class OracleGISSchemaEditor(DatabaseSchemaEditor):
  5. sql_add_geometry_metadata = ("""
  6. INSERT INTO USER_SDO_GEOM_METADATA
  7. ("TABLE_NAME", "COLUMN_NAME", "DIMINFO", "SRID")
  8. VALUES (
  9. %(table)s,
  10. %(column)s,
  11. MDSYS.SDO_DIM_ARRAY(
  12. MDSYS.SDO_DIM_ELEMENT('LONG', %(dim0)s, %(dim2)s, %(tolerance)s),
  13. MDSYS.SDO_DIM_ELEMENT('LAT', %(dim1)s, %(dim3)s, %(tolerance)s)
  14. ),
  15. %(srid)s
  16. )""")
  17. sql_add_spatial_index = 'CREATE INDEX %(index)s ON %(table)s(%(column)s) INDEXTYPE IS MDSYS.SPATIAL_INDEX'
  18. sql_drop_spatial_index = 'DROP INDEX %(index)s'
  19. sql_clear_geometry_table_metadata = 'DELETE FROM USER_SDO_GEOM_METADATA WHERE TABLE_NAME = %(table)s'
  20. sql_clear_geometry_field_metadata = (
  21. 'DELETE FROM USER_SDO_GEOM_METADATA WHERE TABLE_NAME = %(table)s '
  22. 'AND COLUMN_NAME = %(column)s'
  23. )
  24. def __init__(self, *args, **kwargs):
  25. super().__init__(*args, **kwargs)
  26. self.geometry_sql = []
  27. def geo_quote_name(self, name):
  28. return self.connection.ops.geo_quote_name(name)
  29. def column_sql(self, model, field, include_default=False):
  30. column_sql = super().column_sql(model, field, include_default)
  31. if isinstance(field, GeometryField):
  32. db_table = model._meta.db_table
  33. self.geometry_sql.append(
  34. self.sql_add_geometry_metadata % {
  35. 'table': self.geo_quote_name(db_table),
  36. 'column': self.geo_quote_name(field.column),
  37. 'dim0': field._extent[0],
  38. 'dim1': field._extent[1],
  39. 'dim2': field._extent[2],
  40. 'dim3': field._extent[3],
  41. 'tolerance': field._tolerance,
  42. 'srid': field.srid,
  43. }
  44. )
  45. if field.spatial_index:
  46. self.geometry_sql.append(
  47. self.sql_add_spatial_index % {
  48. 'index': self.quote_name(self._create_spatial_index_name(model, field)),
  49. 'table': self.quote_name(db_table),
  50. 'column': self.quote_name(field.column),
  51. }
  52. )
  53. return column_sql
  54. def create_model(self, model):
  55. super().create_model(model)
  56. self.run_geometry_sql()
  57. def delete_model(self, model):
  58. super().delete_model(model)
  59. self.execute(self.sql_clear_geometry_table_metadata % {
  60. 'table': self.geo_quote_name(model._meta.db_table),
  61. })
  62. def add_field(self, model, field):
  63. super().add_field(model, field)
  64. self.run_geometry_sql()
  65. def remove_field(self, model, field):
  66. if isinstance(field, GeometryField):
  67. self.execute(self.sql_clear_geometry_field_metadata % {
  68. 'table': self.geo_quote_name(model._meta.db_table),
  69. 'column': self.geo_quote_name(field.column),
  70. })
  71. if field.spatial_index:
  72. self.execute(self.sql_drop_spatial_index % {
  73. 'index': self.quote_name(self._create_spatial_index_name(model, field)),
  74. })
  75. super().remove_field(model, field)
  76. def run_geometry_sql(self):
  77. for sql in self.geometry_sql:
  78. self.execute(sql)
  79. self.geometry_sql = []
  80. def _create_spatial_index_name(self, model, field):
  81. # Oracle doesn't allow object names > 30 characters. Use this scheme
  82. # instead of self._create_index_name() for backwards compatibility.
  83. return truncate_name('%s_%s_id' % (strip_quotes(model._meta.db_table), field.column), 30)