Development of an internal social media platform with personalised dashboards for students
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 2.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from django.db.backends.postgresql.schema import DatabaseSchemaEditor
  2. class PostGISSchemaEditor(DatabaseSchemaEditor):
  3. geom_index_type = 'GIST'
  4. geom_index_ops_nd = 'GIST_GEOMETRY_OPS_ND'
  5. rast_index_wrapper = 'ST_ConvexHull(%s)'
  6. sql_alter_column_to_3d = "ALTER COLUMN %(column)s TYPE %(type)s USING ST_Force3D(%(column)s)::%(type)s"
  7. sql_alter_column_to_2d = "ALTER COLUMN %(column)s TYPE %(type)s USING ST_Force2D(%(column)s)::%(type)s"
  8. def geo_quote_name(self, name):
  9. return self.connection.ops.geo_quote_name(name)
  10. def _field_should_be_indexed(self, model, field):
  11. if getattr(field, 'spatial_index', False):
  12. return True
  13. return super()._field_should_be_indexed(model, field)
  14. def _create_index_sql(self, model, fields, **kwargs):
  15. if len(fields) != 1 or not hasattr(fields[0], 'geodetic'):
  16. return super()._create_index_sql(model, fields, **kwargs)
  17. field = fields[0]
  18. field_column = self.quote_name(field.column)
  19. if field.geom_type == 'RASTER':
  20. # For raster fields, wrap index creation SQL statement with ST_ConvexHull.
  21. # Indexes on raster columns are based on the convex hull of the raster.
  22. field_column = self.rast_index_wrapper % field_column
  23. elif field.dim > 2 and not field.geography:
  24. # Use "nd" ops which are fast on multidimensional cases
  25. field_column = "%s %s" % (field_column, self.geom_index_ops_nd)
  26. return self.sql_create_index % {
  27. "name": self.quote_name('%s_%s_id' % (model._meta.db_table, field.column)),
  28. "table": self.quote_name(model._meta.db_table),
  29. "using": "USING %s" % self.geom_index_type,
  30. "columns": field_column,
  31. "extra": '',
  32. }
  33. def _alter_column_type_sql(self, table, old_field, new_field, new_type):
  34. """
  35. Special case when dimension changed.
  36. """
  37. if not hasattr(old_field, 'dim') or not hasattr(new_field, 'dim'):
  38. return super()._alter_column_type_sql(table, old_field, new_field, new_type)
  39. if old_field.dim == 2 and new_field.dim == 3:
  40. sql_alter = self.sql_alter_column_to_3d
  41. elif old_field.dim == 3 and new_field.dim == 2:
  42. sql_alter = self.sql_alter_column_to_2d
  43. else:
  44. sql_alter = self.sql_alter_column_type
  45. return (
  46. (
  47. sql_alter % {
  48. "column": self.quote_name(new_field.column),
  49. "type": new_type,
  50. },
  51. [],
  52. ),
  53. [],
  54. )