Refs #30123 -- Simplified introspection of geography columns on PostGIS.
This commit is contained in:
parent
327bbaae24
commit
8d01edfa65
|
@ -3,9 +3,7 @@ from django.db.backends.postgresql.introspection import DatabaseIntrospection
|
||||||
|
|
||||||
|
|
||||||
class PostGISIntrospection(DatabaseIntrospection):
|
class PostGISIntrospection(DatabaseIntrospection):
|
||||||
# Reverse dictionary for PostGIS geometry types not populated until
|
postgis_oid_lookup = {} # Populated when introspection is performed.
|
||||||
# introspection is actually performed.
|
|
||||||
postgis_types_reverse = {}
|
|
||||||
|
|
||||||
ignored_tables = DatabaseIntrospection.ignored_tables + [
|
ignored_tables = DatabaseIntrospection.ignored_tables + [
|
||||||
'geography_columns',
|
'geography_columns',
|
||||||
|
@ -15,42 +13,17 @@ class PostGISIntrospection(DatabaseIntrospection):
|
||||||
'raster_overviews',
|
'raster_overviews',
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_postgis_types(self):
|
|
||||||
"""
|
|
||||||
Return a dictionary with keys that are the PostgreSQL object
|
|
||||||
identification integers for the PostGIS geometry and/or
|
|
||||||
geography types (if supported).
|
|
||||||
"""
|
|
||||||
field_types = [
|
|
||||||
('geometry', 'GeometryField'),
|
|
||||||
# The value for the geography type is actually a tuple
|
|
||||||
# to pass in the `geography=True` keyword to the field
|
|
||||||
# definition.
|
|
||||||
('geography', ('GeometryField', {'geography': True})),
|
|
||||||
]
|
|
||||||
postgis_types = {}
|
|
||||||
|
|
||||||
# The OID integers associated with the geometry type may
|
|
||||||
# be different across versions; hence, this is why we have
|
|
||||||
# to query the PostgreSQL pg_type table corresponding to the
|
|
||||||
# PostGIS custom data types.
|
|
||||||
oid_sql = 'SELECT "oid" FROM "pg_type" WHERE "typname" = %s'
|
|
||||||
with self.connection.cursor() as cursor:
|
|
||||||
for field_type in field_types:
|
|
||||||
cursor.execute(oid_sql, (field_type[0],))
|
|
||||||
for result in cursor.fetchall():
|
|
||||||
postgis_types[result[0]] = field_type[1]
|
|
||||||
return postgis_types
|
|
||||||
|
|
||||||
def get_field_type(self, data_type, description):
|
def get_field_type(self, data_type, description):
|
||||||
if not self.postgis_types_reverse:
|
if not self.postgis_oid_lookup:
|
||||||
# If the PostGIS types reverse dictionary is not populated, do so
|
# Query PostgreSQL's pg_type table to determine the OID integers
|
||||||
# now. In order to prevent unnecessary requests upon connection
|
# for the PostGIS data types used in reverse lookup (the integers
|
||||||
# initialization, the `data_types_reverse` dictionary is not updated
|
# may be different across versions). To prevent unnecessary
|
||||||
# with the PostGIS custom types until introspection is actually
|
# requests upon connection initialization, the `data_types_reverse`
|
||||||
# performed -- in other words, when this function is called.
|
# dictionary isn't updated until introspection is performed here.
|
||||||
self.postgis_types_reverse = self.get_postgis_types()
|
with self.connection.cursor() as cursor:
|
||||||
self.data_types_reverse.update(self.postgis_types_reverse)
|
cursor.execute("SELECT oid, typname FROM pg_type WHERE typname IN ('geometry', 'geography')")
|
||||||
|
self.postgis_oid_lookup = dict(cursor.fetchall())
|
||||||
|
self.data_types_reverse.update((oid, 'GeometryField') for oid in self.postgis_oid_lookup)
|
||||||
return super().get_field_type(data_type, description)
|
return super().get_field_type(data_type, description)
|
||||||
|
|
||||||
def get_geometry_type(self, table_name, description):
|
def get_geometry_type(self, table_name, description):
|
||||||
|
@ -78,6 +51,8 @@ class PostGISIntrospection(DatabaseIntrospection):
|
||||||
field_type = OGRGeomType(field_type).django
|
field_type = OGRGeomType(field_type).django
|
||||||
# Getting any GeometryField keyword arguments that are not the default.
|
# Getting any GeometryField keyword arguments that are not the default.
|
||||||
field_params = {}
|
field_params = {}
|
||||||
|
if self.postgis_oid_lookup.get(description.type_code) == 'geography':
|
||||||
|
field_params['geography'] = True
|
||||||
if srid != 4326:
|
if srid != 4326:
|
||||||
field_params['srid'] = srid
|
field_params['srid'] = srid
|
||||||
if dim != 2:
|
if dim != 2:
|
||||||
|
|
Loading…
Reference in New Issue