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.

introspection.py 3.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from django.contrib.gis.gdal import OGRGeomType
  2. from django.db.backends.sqlite3.introspection import (
  3. DatabaseIntrospection, FlexibleFieldLookupDict,
  4. )
  5. class GeoFlexibleFieldLookupDict(FlexibleFieldLookupDict):
  6. """
  7. Sublcass that includes updates the `base_data_types_reverse` dict
  8. for geometry field types.
  9. """
  10. base_data_types_reverse = {
  11. **FlexibleFieldLookupDict.base_data_types_reverse,
  12. 'point': 'GeometryField',
  13. 'linestring': 'GeometryField',
  14. 'polygon': 'GeometryField',
  15. 'multipoint': 'GeometryField',
  16. 'multilinestring': 'GeometryField',
  17. 'multipolygon': 'GeometryField',
  18. 'geometrycollection': 'GeometryField',
  19. }
  20. class SpatiaLiteIntrospection(DatabaseIntrospection):
  21. data_types_reverse = GeoFlexibleFieldLookupDict()
  22. def get_geometry_type(self, table_name, geo_col):
  23. with self.connection.cursor() as cursor:
  24. # Querying the `geometry_columns` table to get additional metadata.
  25. cursor.execute('SELECT coord_dimension, srid, geometry_type '
  26. 'FROM geometry_columns '
  27. 'WHERE f_table_name=%s AND f_geometry_column=%s',
  28. (table_name, geo_col))
  29. row = cursor.fetchone()
  30. if not row:
  31. raise Exception('Could not find a geometry column for "%s"."%s"' %
  32. (table_name, geo_col))
  33. # OGRGeomType does not require GDAL and makes it easy to convert
  34. # from OGC geom type name to Django field.
  35. ogr_type = row[2]
  36. if isinstance(ogr_type, int) and ogr_type > 1000:
  37. # SpatiaLite uses SFSQL 1.2 offsets 1000 (Z), 2000 (M), and
  38. # 3000 (ZM) to indicate the presence of higher dimensional
  39. # coordinates (M not yet supported by Django).
  40. ogr_type = ogr_type % 1000 + OGRGeomType.wkb25bit
  41. field_type = OGRGeomType(ogr_type).django
  42. # Getting any GeometryField keyword arguments that are not the default.
  43. dim = row[0]
  44. srid = row[1]
  45. field_params = {}
  46. if srid != 4326:
  47. field_params['srid'] = srid
  48. if (isinstance(dim, str) and 'Z' in dim) or dim == 3:
  49. field_params['dim'] = 3
  50. return field_type, field_params
  51. def get_constraints(self, cursor, table_name):
  52. constraints = super().get_constraints(cursor, table_name)
  53. cursor.execute('SELECT f_geometry_column '
  54. 'FROM geometry_columns '
  55. 'WHERE f_table_name=%s AND spatial_index_enabled=1', (table_name,))
  56. for row in cursor.fetchall():
  57. constraints['%s__spatial__index' % row[0]] = {
  58. "columns": [row[0]],
  59. "primary_key": False,
  60. "unique": False,
  61. "foreign_key": None,
  62. "check": False,
  63. "index": True,
  64. }
  65. return constraints