diff options
| author | Tim Graham <timograham@gmail.com> | 2014-07-26 16:55:31 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2014-08-01 10:26:00 -0400 |
| commit | a9bdce7e5503a450c2c291fb2cb1e2097617ba75 (patch) | |
| tree | bd200ec7a07fde071cf8ff663ee71ce1f450a6ab /django | |
| parent | 7ce4ef58c95fc17d4914e1962608aad79d7c46f1 (diff) | |
Fixed #23108 -- Dropped support for PostgreSQL 8.4 & PostGIS 1.3, 1.4.
Thanks Claude Paroz for the review.
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/gis/db/backends/postgis/introspection.py | 18 | ||||
| -rw-r--r-- | django/contrib/gis/db/backends/postgis/operations.py | 66 | ||||
| -rw-r--r-- | django/contrib/gis/db/models/query.py | 32 | ||||
| -rw-r--r-- | django/contrib/gis/tests/distapp/tests.py | 18 | ||||
| -rw-r--r-- | django/contrib/gis/tests/geo3d/tests.py | 2 | ||||
| -rw-r--r-- | django/contrib/gis/tests/geoapp/tests.py | 21 | ||||
| -rw-r--r-- | django/contrib/gis/tests/geogapp/tests.py | 2 | ||||
| -rw-r--r-- | django/db/backends/postgresql_psycopg2/version.py | 12 |
8 files changed, 52 insertions, 119 deletions
diff --git a/django/contrib/gis/db/backends/postgis/introspection.py b/django/contrib/gis/db/backends/postgis/introspection.py index af46ad56fc..631844a030 100644 --- a/django/contrib/gis/db/backends/postgis/introspection.py +++ b/django/contrib/gis/db/backends/postgis/introspection.py @@ -25,12 +25,13 @@ class PostGISIntrospection(DatabaseIntrospection): identification integers for the PostGIS geometry and/or geography types (if supported). """ - field_types = [('geometry', 'GeometryField')] - if self.connection.ops.geography: + 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. - field_types.append(('geography', ('GeometryField', {'geography': True}))) + ('geography', ('GeometryField', {'geography': True})), + ] postgis_types = {} # The OID integers associated with the geometry type may @@ -79,12 +80,11 @@ class PostGISIntrospection(DatabaseIntrospection): if not row: raise GeoIntrospectionError except GeoIntrospectionError: - if self.connection.ops.geography: - cursor.execute('SELECT "coord_dimension", "srid", "type" ' - 'FROM "geography_columns" ' - 'WHERE "f_table_name"=%s AND "f_geography_column"=%s', - (table_name, geo_col)) - row = cursor.fetchone() + cursor.execute('SELECT "coord_dimension", "srid", "type" ' + 'FROM "geography_columns" ' + 'WHERE "f_table_name"=%s AND "f_geography_column"=%s', + (table_name, geo_col)) + row = cursor.fetchone() if not row: raise Exception('Could not find a geometry or geography column for "%s"."%s"' % diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py index de4c6c81d2..4fae107d5e 100644 --- a/django/contrib/gis/db/backends/postgis/operations.py +++ b/django/contrib/gis/db/backends/postgis/operations.py @@ -74,6 +74,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): compiler_module = 'django.contrib.gis.db.models.sql.compiler' name = 'postgis' postgis = True + geography = True geom_func_prefix = 'ST_' version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)') valid_aggregates = {'Collect', 'Extent', 'Extent3D', 'MakeLine', 'Union'} @@ -140,6 +141,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): 'relate': (PostGISRelate, six.string_types), 'coveredby': PostGISFunction(prefix, 'CoveredBy'), 'covers': PostGISFunction(prefix, 'Covers'), + 'contains_properly': PostGISFunction(prefix, 'ContainsProperly'), } # Valid distance types and substitutions @@ -162,34 +164,17 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): # Adding the distance functions to the geometries lookup. self.geometry_functions.update(self.distance_functions) - # Only PostGIS versions 1.3.4+ have GeoJSON serialization support. - if self.spatial_version < (1, 3, 4): - GEOJSON = False - else: - GEOJSON = prefix + 'AsGeoJson' - - # ST_ContainsProperly ST_MakeLine, and ST_GeoHash added in 1.4. - if self.spatial_version >= (1, 4, 0): - GEOHASH = 'ST_GeoHash' - BOUNDINGCIRCLE = 'ST_MinimumBoundingCircle' - self.geometry_functions['contains_properly'] = PostGISFunction(prefix, 'ContainsProperly') - else: - GEOHASH, BOUNDINGCIRCLE = False, False - - # Geography type support added in 1.5. - if self.spatial_version >= (1, 5, 0): - self.geography = True - # Only a subset of the operators and functions are available - # for the geography type. - self.geography_functions = self.distance_functions.copy() - self.geography_functions.update({ - 'coveredby': self.geometry_functions['coveredby'], - 'covers': self.geometry_functions['covers'], - 'intersects': self.geometry_functions['intersects'], - }) - self.geography_operators = { - 'bboverlaps': PostGISOperator('&&'), - } + # Only a subset of the operators and functions are available + # for the geography type. + self.geography_functions = self.distance_functions.copy() + self.geography_functions.update({ + 'coveredby': self.geometry_functions['coveredby'], + 'covers': self.geometry_functions['covers'], + 'intersects': self.geometry_functions['intersects'], + }) + self.geography_operators = { + 'bboverlaps': PostGISOperator('&&'), + } # Native geometry type support added in PostGIS 2.0. if self.spatial_version >= (2, 0, 0): @@ -201,7 +186,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): self.gis_terms.update(self.geometry_functions) self.area = prefix + 'Area' - self.bounding_circle = BOUNDINGCIRCLE + self.bounding_circle = prefix + 'MinimumBoundingCircle' self.centroid = prefix + 'Centroid' self.collect = prefix + 'Collect' self.difference = prefix + 'Difference' @@ -211,8 +196,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): self.envelope = prefix + 'Envelope' self.extent = prefix + 'Extent' self.force_rhr = prefix + 'ForceRHR' - self.geohash = GEOHASH - self.geojson = GEOJSON + self.geohash = prefix + 'GeoHash' + self.geojson = prefix + 'AsGeoJson' self.gml = prefix + 'AsGML' self.intersection = prefix + 'Intersection' self.kml = prefix + 'AsKML' @@ -261,7 +246,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): except ProgrammingError: raise ImproperlyConfigured( 'Cannot determine PostGIS version for database "%s". ' - 'GeoDjango requires at least PostGIS version 1.3. ' + 'GeoDjango requires at least PostGIS version 1.5. ' 'Was the database created from a spatial database ' 'template?' % self.connection.settings_dict['NAME'] ) @@ -315,12 +300,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): has been specified to be of geography type instead. """ if f.geography: - if not self.geography: - raise NotImplementedError('PostGIS 1.5 required for geography column support.') - if f.srid != 4326: - raise NotImplementedError('PostGIS 1.5 supports geography columns ' - 'only with an SRID of 4326.') + raise NotImplementedError('PostGIS only supports geography columns with an SRID of 4326.') return 'geography(%s,%d)' % (f.geom_type, f.srid) elif self.geometry: @@ -352,7 +333,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): # Shorthand boolean flags. geodetic = f.geodetic(self.connection) - geography = f.geography and self.geography + geography = f.geography if isinstance(value, Distance): if geography: @@ -525,15 +506,6 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): op = op(self.geom_func_prefix, value[1]) elif lookup_type in self.distance_functions and lookup_type != 'dwithin': if not field.geography and field.geodetic(self.connection): - # Geodetic distances are only available from Points to - # PointFields on PostGIS 1.4 and below. - if not self.connection.ops.geography: - if field.geom_type != 'POINT': - raise ValueError('PostGIS spherical operations are only valid on PointFields.') - - if str(geom.geom_type) != 'Point': - raise ValueError('PostGIS geometry distance parameter is required to be of type Point.') - # Setting up the geodetic operation appropriately. if nparams == 3 and value[2] == 'spheroid': op = op['spheroid'] diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py index 4080ccb3a2..a9a7bb7f6f 100644 --- a/django/contrib/gis/db/models/query.py +++ b/django/contrib/gis/db/models/query.py @@ -151,24 +151,13 @@ class GeoQuerySet(QuerySet): if not isinstance(precision, six.integer_types): raise TypeError('Precision keyword must be set with an integer.') - # Setting the options flag -- which depends on which version of - # PostGIS we're using. SpatiaLite only uses the first group of options. - if backend.spatial_version >= (1, 4, 0): - options = 0 - if crs and bbox: - options = 3 - elif bbox: - options = 1 - elif crs: - options = 2 - else: - options = 0 - if crs and bbox: - options = 3 - elif crs: - options = 1 - elif bbox: - options = 2 + options = 0 + if crs and bbox: + options = 3 + elif bbox: + options = 1 + elif crs: + options = 2 s = {'desc': 'GeoJSON', 'procedure_args': {'precision': precision, 'options': options}, 'procedure_fmt': '%(geo_col)s,%(precision)s,%(options)s', @@ -197,12 +186,7 @@ class GeoQuerySet(QuerySet): backend = connections[self.db].ops s = {'desc': 'GML', 'procedure_args': {'precision': precision}} if backend.postgis: - # PostGIS AsGML() aggregate function parameter order depends on the - # version -- uggh. - if backend.spatial_version > (1, 3, 1): - s['procedure_fmt'] = '%(version)s,%(geo_col)s,%(precision)s' - else: - s['procedure_fmt'] = '%(geo_col)s,%(precision)s,%(version)s' + s['procedure_fmt'] = '%(version)s,%(geo_col)s,%(precision)s' s['procedure_args'] = {'precision': precision, 'version': version} return self._spatial_attribute('gml', s, **kwargs) diff --git a/django/contrib/gis/tests/distapp/tests.py b/django/contrib/gis/tests/distapp/tests.py index 14abbb8981..0a19bc505d 100644 --- a/django/contrib/gis/tests/distapp/tests.py +++ b/django/contrib/gis/tests/distapp/tests.py @@ -147,7 +147,7 @@ class DistanceTest(TestCase): # Testing geodetic distance calculation with a non-point geometry # (a LineString of Wollongong and Shellharbour coords). ls = LineString(((150.902, -34.4245), (150.87, -34.5789))) - if oracle or connection.ops.geography: + if oracle or postgis: # Reference query: # SELECT ST_distance_sphere(point, ST_GeomFromText('LINESTRING(150.9020 -34.4245,150.8700 -34.5789)', 4326)) FROM distapp_australiacity ORDER BY name; distances = [1120954.92533513, 140575.720018241, 640396.662906304, @@ -157,11 +157,6 @@ class DistanceTest(TestCase): for city, distance in zip(qs, distances): # Testing equivalence to within a meter. self.assertAlmostEqual(distance, city.distance.m, 0) - else: - # PostGIS 1.4 and below is limited to disance queries only - # to/from point geometries, check for raising of ValueError. - self.assertRaises(ValueError, AustraliaCity.objects.distance, ls) - self.assertRaises(ValueError, AustraliaCity.objects.distance, ls.wkt) # Got the reference distances using the raw SQL statements: # SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11)); @@ -204,11 +199,6 @@ class DistanceTest(TestCase): """ Test the `distance` GeoQuerySet method used with `transform` on a geographic field. """ - # Normally you can't compute distances from a geometry field - # that is not a PointField (on PostGIS 1.4 and below). - if not connection.ops.geography: - self.assertRaises(ValueError, CensusZipcode.objects.distance, self.stx_pnt) - # We'll be using a Polygon (created by buffering the centroid # of 77005 to 100m) -- which aren't allowed in geographic distance # queries normally, however our field has been transformed to @@ -272,15 +262,15 @@ class DistanceTest(TestCase): line = GEOSGeometry('LINESTRING(144.9630 -37.8143,151.2607 -33.8870)', 4326) dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line, D(km=100))) - if oracle or connection.ops.geography: - # Oracle and PostGIS 1.5 can do distance lookups on arbitrary geometries. + if oracle or postgis: + # Oracle and PostGIS can do distance lookups on arbitrary geometries. self.assertEqual(9, dist_qs.count()) self.assertEqual(['Batemans Bay', 'Canberra', 'Hillsdale', 'Melbourne', 'Mittagong', 'Shellharbour', 'Sydney', 'Thirroul', 'Wollongong'], self.get_names(dist_qs)) else: - # PostGIS 1.4 and below only allows geodetic distance queries (utilizing + # spatialite only allow geodetic distance queries (utilizing # ST_Distance_Sphere/ST_Distance_Spheroid) from Points to PointFields # on geometry columns. self.assertRaises(ValueError, dist_qs.count) diff --git a/django/contrib/gis/tests/geo3d/tests.py b/django/contrib/gis/tests/geo3d/tests.py index 2c7f93859a..130124c00c 100644 --- a/django/contrib/gis/tests/geo3d/tests.py +++ b/django/contrib/gis/tests/geo3d/tests.py @@ -70,7 +70,7 @@ class Geo3DTest(TestCase): available within GeoDjango. For more information, see the PostGIS docs on the routines that support 3D: - http://postgis.refractions.net/documentation/manual-1.4/ch08.html#PostGIS_3D_Functions + http://postgis.refractions.net/documentation/manual-1.5/ch08.html#PostGIS_3D_Functions """ def _load_interstate_data(self): diff --git a/django/contrib/gis/tests/geoapp/tests.py b/django/contrib/gis/tests/geoapp/tests.py index 2e572c4052..f105da3672 100644 --- a/django/contrib/gis/tests/geoapp/tests.py +++ b/django/contrib/gis/tests/geoapp/tests.py @@ -507,11 +507,7 @@ class GeoQuerySetTest(TestCase): houston_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}' victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.305196,48.462611]}' chicago_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}' - if postgis and connection.ops.spatial_version < (1, 4, 0): - pueblo_json = '{"type":"Point","coordinates":[-104.60925200,38.25500100]}' - houston_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"coordinates":[-95.36315100,29.76337400]}' - victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.30519600,48.46261100]}' - elif spatialite: + if spatialite: victoria_json = '{"type":"Point","bbox":[-123.305196,48.462611,-123.305196,48.462611],"coordinates":[-123.305196,48.462611]}' # Precision argument should only be an integer @@ -560,10 +556,8 @@ class GeoQuerySetTest(TestCase): for ptown in [ptown1, ptown2]: self.assertTrue(gml_regex.match(ptown.gml)) - # PostGIS < 1.5 doesn't include dimension im GMLv3 output. - if postgis and connection.ops.spatial_version >= (1, 5, 0): - self.assertIn('<gml:pos srsDimension="2">', - City.objects.gml(version=3).get(name='Pueblo').gml) + if postgis: + self.assertIn('<gml:pos srsDimension="2">', City.objects.gml(version=3).get(name='Pueblo').gml) def test_kml(self): "Testing KML output from the database using GeoQuerySet.kml()." @@ -577,18 +571,11 @@ class GeoQuerySetTest(TestCase): qs = City.objects.all() self.assertRaises(TypeError, qs.kml, 'name') - # The reference KML depends on the version of PostGIS used - # (the output stopped including altitude in 1.3.3). - if connection.ops.spatial_version >= (1, 3, 3): - ref_kml = '<Point><coordinates>-104.609252,38.255001</coordinates></Point>' - else: - ref_kml = '<Point><coordinates>-104.609252,38.255001,0</coordinates></Point>' - # Ensuring the KML is as expected. ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo') ptown2 = City.objects.kml(precision=9).get(name='Pueblo') for ptown in [ptown1, ptown2]: - self.assertEqual(ref_kml, ptown.kml) + self.assertEqual('<Point><coordinates>-104.609252,38.255001</coordinates></Point>', ptown.kml) # Only PostGIS has support for the MakeLine aggregate. @no_mysql diff --git a/django/contrib/gis/tests/geogapp/tests.py b/django/contrib/gis/tests/geogapp/tests.py index 615c142324..92f12b9272 100644 --- a/django/contrib/gis/tests/geogapp/tests.py +++ b/django/contrib/gis/tests/geogapp/tests.py @@ -1,5 +1,5 @@ """ -Tests for geography support in PostGIS 1.5+ +Tests for geography support in PostGIS """ from __future__ import unicode_literals diff --git a/django/db/backends/postgresql_psycopg2/version.py b/django/db/backends/postgresql_psycopg2/version.py index 64fd7c8298..d558fb2e51 100644 --- a/django/db/backends/postgresql_psycopg2/version.py +++ b/django/db/backends/postgresql_psycopg2/version.py @@ -6,10 +6,10 @@ import re # This reg-exp is intentionally fairly flexible here. # Needs to be able to handle stuff like: -# PostgreSQL 8.3.6 -# EnterpriseDB 8.3 -# PostgreSQL 8.3 beta4 -# PostgreSQL 8.4beta1 +# PostgreSQL #.#.# +# EnterpriseDB #.# +# PostgreSQL #.# beta# +# PostgreSQL #.#beta# VERSION_RE = re.compile(r'\S+ (\d+)\.(\d+)\.?(\d+)?') @@ -29,8 +29,8 @@ def get_version(connection): PQServerVersion()/``server_version`` connection attribute (available in newer psycopg2 versions.) - For example, 80304 for 8.3.4. The last two digits will be 00 in the case of - releases (e.g., 80400 for 'PostgreSQL 8.4') or in the case of beta and + For example, 90304 for 9.3.4. The last two digits will be 00 in the case of + releases (e.g., 90400 for 'PostgreSQL 9.4') or in the case of beta and prereleases (e.g. 90100 for 'PostgreSQL 9.1beta2'). PQServerVersion()/``server_version`` doesn't execute a query so try that |
