Fixed #30155 -- Dropped support for PostgreSQL 9.4 and PostGIS 2.1.

This commit is contained in:
Tim Graham 2019-02-04 11:07:46 -05:00
parent d47498c5df
commit 39ebdf5a3c
13 changed files with 21 additions and 78 deletions

View File

@ -151,13 +151,6 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
'BoundingCircle': 'ST_MinimumBoundingCircle',
'NumPoints': 'ST_NPoints',
}
if self.spatial_version < (2, 2, 0):
function_names.update({
'DistanceSphere': 'ST_distance_sphere',
'DistanceSpheroid': 'ST_distance_spheroid',
'LengthSpheroid': 'ST_length_spheroid',
'MemSize': 'ST_mem_size',
})
if self.spatial_version < (2, 4, 0):
function_names['ForcePolygonCW'] = 'ST_ForceRHR'
return function_names
@ -185,7 +178,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
raise ImproperlyConfigured(
'Cannot determine PostGIS version for database "%s" '
'using command "SELECT postgis_lib_version()". '
'GeoDjango requires at least PostGIS version 2.1. '
'GeoDjango requires at least PostGIS version 2.2. '
'Was the database created from a spatial database '
'template?' % self.connection.settings_dict['NAME']
)

View File

@ -55,8 +55,6 @@ class BrinIndex(PostgresIndex):
return path, args, kwargs
def check_supported(self, schema_editor):
if not schema_editor.connection.features.has_brin_index_support:
raise NotSupportedError('BRIN indexes require PostgreSQL 9.5+.')
if self.autosummarize and not schema_editor.connection.features.has_brin_autosummarize:
raise NotSupportedError('BRIN option autosummarize requires PostgreSQL 10+.')
@ -105,10 +103,6 @@ class GinIndex(PostgresIndex):
kwargs['gin_pending_list_limit'] = self.gin_pending_list_limit
return path, args, kwargs
def check_supported(self, schema_editor):
if self.gin_pending_list_limit and not schema_editor.connection.features.has_gin_pending_list_limit:
raise NotSupportedError('GIN option gin_pending_list_limit requires PostgreSQL 9.5+.')
def get_with_params(self):
with_params = []
if self.gin_pending_list_limit is not None:

View File

@ -16,6 +16,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
has_select_for_update = True
has_select_for_update_nowait = True
has_select_for_update_of = True
has_select_for_update_skip_locked = True
can_release_savepoints = True
supports_tablespaces = True
supports_transactions = True
@ -55,10 +56,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supported_explain_formats = {'JSON', 'TEXT', 'XML', 'YAML'}
validates_explain_options = False # A query will error on invalid options.
@cached_property
def is_postgresql_9_5(self):
return self.connection.pg_version >= 90500
@cached_property
def is_postgresql_9_6(self):
return self.connection.pg_version >= 90600
@ -67,11 +64,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
def is_postgresql_10(self):
return self.connection.pg_version >= 100000
has_select_for_update_skip_locked = property(operator.attrgetter('is_postgresql_9_5'))
has_brin_index_support = property(operator.attrgetter('is_postgresql_9_5'))
has_jsonb_agg = property(operator.attrgetter('is_postgresql_9_5'))
has_brin_autosummarize = property(operator.attrgetter('is_postgresql_10'))
has_gin_pending_list_limit = property(operator.attrgetter('is_postgresql_9_5'))
supports_ignore_conflicts = property(operator.attrgetter('is_postgresql_9_5'))
has_phraseto_tsquery = property(operator.attrgetter('is_postgresql_9_6'))
supports_table_partitions = property(operator.attrgetter('is_postgresql_10'))

View File

@ -12,7 +12,7 @@ Program Description Required
`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 5.2, 5.1, 5.0, 4.x
:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 2.3, 2.2, 2.1, 2.0, 1.11
:doc:`GeoIP <../geoip2>` IP-based geolocation library No 2
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.5, 2.4, 2.3, 2.2, 2.1
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 2.5, 2.4, 2.3, 2.2
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.3
======================== ==================================== ================================ ===================================
@ -30,7 +30,6 @@ totally fine with GeoDjango. Your mileage may vary.
GDAL 2.1.0 2016-04
GDAL 2.2.0 2017-05
GDAL 2.3.0 2018-05
PostGIS 2.1.0 2013-08-17
PostGIS 2.2.0 2015-10-17
PostGIS 2.3.0 2016-09-26
PostGIS 2.4.0 2017-09-30

View File

@ -58,7 +58,7 @@ supported versions, and any notes for each of the supported database backends:
================== ============================== ================== =========================================
Database Library Requirements Supported Versions Notes
================== ============================== ================== =========================================
PostgreSQL GEOS, GDAL, PROJ.4, PostGIS 9.4+ Requires PostGIS.
PostgreSQL GEOS, GDAL, PROJ.4, PostGIS 9.5+ Requires PostGIS.
MySQL GEOS, GDAL 5.6+ Not OGC-compliant; :ref:`limited functionality <mysql-spatial-limitations>`.
Oracle GEOS, GDAL 12.1+ XE not supported.
SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.8.3+ Requires SpatiaLite 4.3+

View File

@ -90,7 +90,7 @@ General-purpose aggregation functions
.. class:: JSONBAgg(expressions, filter=None, **extra)
Returns the input values as a ``JSON`` array. Requires PostgreSQL ≥ 9.5.
Returns the input values as a ``JSON`` array.
``StringAgg``
-------------

View File

@ -61,7 +61,7 @@ available from the ``django.contrib.postgres.indexes`` module.
Provide an integer number of bytes to the gin_pending_list_limit_ parameter
to tune the maximum size of the GIN pending list which is used when
``fastupdate`` is enabled. This parameter requires PostgreSQL ≥ 9.5.
``fastupdate`` is enabled.
.. _GIN Fast Update Technique: https://www.postgresql.org/docs/current/static/gin-implementation.html#GIN-FAST-UPDATE
.. _gin_pending_list_limit: https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-GIN-PENDING-LIST-LIMIT

View File

@ -92,7 +92,7 @@ below for information on how to set up your database correctly.
PostgreSQL notes
================
Django supports PostgreSQL 9.4 and higher. `psycopg2`_ 2.5.4 or higher is
Django supports PostgreSQL 9.5 and higher. `psycopg2`_ 2.5.4 or higher is
required, though the latest release is recommended.
.. _psycopg2: http://initd.org/psycopg/

View File

@ -2073,11 +2073,11 @@ The ``batch_size`` parameter controls how many objects are created in a single
query. The default is to create all objects in one batch, except for SQLite
where the default is such that at most 999 variables per query are used.
On databases that support it (all except PostgreSQL < 9.5 and Oracle), setting
the ``ignore_conflicts`` parameter to ``True`` tells the database to ignore
failure to insert any rows that fail constraints such as duplicate unique
values. Enabling this parameter disables setting the primary key on each model
instance (if the database normally supports it).
On databases that support it (all but Oracle), setting the ``ignore_conflicts``
parameter to ``True`` tells the database to ignore failure to insert any rows
that fail constraints such as duplicate unique values. Enabling this parameter
disables setting the primary key on each model instance (if the database
normally supports it).
.. versionchanged:: 2.2

View File

@ -225,8 +225,16 @@ backends.
:mod:`django.contrib.gis`
-------------------------
* Supported for PostGIS 2.1 is removed.
* Support for SpatiaLite 4.1 and 4.2 is removed.
Dropped support for PostgreSQL 9.4
----------------------------------
Upstream support for PostgreSQL 9.4 ends in December 2019. Django 3.0 supports
PostgreSQL 9.5 and higher.
Miscellaneous
-------------

View File

@ -81,21 +81,3 @@ class TestPostGISVersionCheck(unittest.TestCase):
ops = FakePostGISOperations()
with self.assertRaises(ImproperlyConfigured):
ops.spatial_version
def test_version_dependent_funcs(self):
"""
Resolve names of functions renamed and deprecated in PostGIS 2.2.0
depending on PostGIS version.
Remove when dropping support for PostGIS 2.1.
"""
ops = FakePostGISOperations('2.2.0')
self.assertEqual(ops.spatial_function_name('DistanceSphere'), 'ST_DistanceSphere')
self.assertEqual(ops.spatial_function_name('DistanceSpheroid'), 'ST_DistanceSpheroid')
self.assertEqual(ops.spatial_function_name('LengthSpheroid'), 'ST_LengthSpheroid')
self.assertEqual(ops.spatial_function_name('MemSize'), 'ST_MemSize')
ops = FakePostGISOperations('2.1.0')
self.assertEqual(ops.spatial_function_name('DistanceSphere'), 'ST_distance_sphere')
self.assertEqual(ops.spatial_function_name('DistanceSpheroid'), 'ST_distance_spheroid')
self.assertEqual(ops.spatial_function_name('LengthSpheroid'), 'ST_length_spheroid')
self.assertEqual(ops.spatial_function_name('MemSize'), 'ST_mem_size')

View File

@ -1,7 +1,6 @@
import json
from django.db.models.expressions import F, Value
from django.test.testcases import skipUnlessDBFeature
from django.test.utils import Approximate
from . import PostgreSQLTestCase
@ -184,12 +183,10 @@ class TestGeneralAggregate(PostgreSQLTestCase):
)
self.assertEqual(values, {'arrayagg': [0, 1, 0, 2]})
@skipUnlessDBFeature('has_jsonb_agg')
def test_json_agg(self):
values = AggregateTestModel.objects.aggregate(jsonagg=JSONBAgg('char_field'))
self.assertEqual(values, {'jsonagg': ['Foo1', 'Foo2', 'Foo4', 'Foo3']})
@skipUnlessDBFeature('has_jsonb_agg')
def test_json_agg_empty(self):
values = AggregateTestModel.objects.none().aggregate(jsonagg=JSONBAgg('integer_field'))
self.assertEqual(values, json.loads('{"jsonagg": []}'))

View File

@ -205,7 +205,6 @@ class SchemaTests(PostgreSQLTestCase):
editor.remove_index(CharFieldModel, index)
self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
@skipUnlessDBFeature('has_gin_pending_list_limit')
def test_gin_parameters(self):
index_name = 'integer_array_gin_params'
index = GinIndex(fields=['field'], name=index_name, fastupdate=True, gin_pending_list_limit=64)
@ -218,17 +217,6 @@ class SchemaTests(PostgreSQLTestCase):
editor.remove_index(IntegerArrayModel, index)
self.assertNotIn(index_name, self.get_constraints(IntegerArrayModel._meta.db_table))
@mock.patch('django.db.backends.postgresql.features.DatabaseFeatures.has_gin_pending_list_limit', False)
def test_gin_parameters_exception(self):
index_name = 'gin_options_exception'
index = GinIndex(fields=['field'], name=index_name, gin_pending_list_limit=64)
msg = 'GIN option gin_pending_list_limit requires PostgreSQL 9.5+.'
with self.assertRaisesMessage(NotSupportedError, msg):
with connection.schema_editor() as editor:
editor.add_index(IntegerArrayModel, index)
self.assertNotIn(index_name, self.get_constraints(IntegerArrayModel._meta.db_table))
@skipUnlessDBFeature('has_brin_index_support')
def test_brin_index(self):
index_name = 'char_field_model_field_brin'
index = BrinIndex(fields=['field'], name=index_name, pages_per_range=4)
@ -241,7 +229,7 @@ class SchemaTests(PostgreSQLTestCase):
editor.remove_index(CharFieldModel, index)
self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
@skipUnlessDBFeature('has_brin_index_support', 'has_brin_autosummarize')
@skipUnlessDBFeature('has_brin_autosummarize')
def test_brin_parameters(self):
index_name = 'char_field_brin_params'
index = BrinIndex(fields=['field'], name=index_name, autosummarize=True)
@ -254,16 +242,6 @@ class SchemaTests(PostgreSQLTestCase):
editor.remove_index(CharFieldModel, index)
self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
def test_brin_index_not_supported(self):
index_name = 'brin_index_exception'
index = BrinIndex(fields=['field'], name=index_name)
with self.assertRaisesMessage(NotSupportedError, 'BRIN indexes require PostgreSQL 9.5+.'):
with mock.patch('django.db.backends.postgresql.features.DatabaseFeatures.has_brin_index_support', False):
with connection.schema_editor() as editor:
editor.add_index(CharFieldModel, index)
self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
@skipUnlessDBFeature('has_brin_index_support')
def test_brin_autosummarize_not_supported(self):
index_name = 'brin_options_exception'
index = BrinIndex(fields=['field'], name=index_name, autosummarize=True)