Browse Source

Fixed #32357 -- Dropped support for PostgreSQL 9.6 and PostGIS 2.3.

Mariusz Felisiak 4 years ago
parent
commit
5371342ed6

+ 1 - 1
django/contrib/gis/db/backends/postgis/operations.py

@@ -179,7 +179,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.3. '
+                    'GeoDjango requires at least PostGIS version 2.4. '
                     'Was the database created from a spatial database '
                     'template?' % self.connection.settings_dict['NAME']
                 )

+ 0 - 4
django/contrib/postgres/indexes.py

@@ -98,10 +98,6 @@ class BrinIndex(PostgresIndex):
             kwargs['pages_per_range'] = self.pages_per_range
         return path, args, kwargs
 
-    def check_supported(self, schema_editor):
-        if self.autosummarize and not schema_editor.connection.features.has_brin_autosummarize:
-            raise NotSupportedError('BRIN option autosummarize requires PostgreSQL 10+.')
-
     def get_with_params(self):
         with_params = []
         if self.autosummarize is not None:

+ 0 - 5
django/contrib/postgres/operations.py

@@ -196,11 +196,6 @@ class CollationOperation(Operation):
             raise NotSupportedError(
                 'Non-deterministic collations require PostgreSQL 12+.'
             )
-        if (
-            self.provider != 'libc' and
-            not schema_editor.connection.features.supports_alternate_collation_providers
-        ):
-            raise NotSupportedError('Non-libc providers require PostgreSQL 10+.')
         args = {'locale': schema_editor.quote_name(self.locale)}
         if self.provider != 'libc':
             args['provider'] = schema_editor.quote_name(self.provider)

+ 4 - 17
django/db/backends/postgresql/features.py

@@ -58,6 +58,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     supports_deferrable_unique_constraints = True
     has_json_operators = True
     json_key_contains_list_matching_requires_list = True
+    test_collations = {
+        'non_default': 'sv-x-icu',
+        'swedish_ci': 'sv-x-icu',
+    }
 
     django_test_skips = {
         'opclasses are PostgreSQL only.': {
@@ -65,16 +69,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
         },
     }
 
-    @cached_property
-    def test_collations(self):
-        # PostgreSQL < 10 doesn't support ICU collations.
-        if self.is_postgresql_10:
-            return {
-                'non_default': 'sv-x-icu',
-                'swedish_ci': 'sv-x-icu',
-            }
-        return {}
-
     @cached_property
     def introspected_field_types(self):
         return {
@@ -84,10 +78,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
             'PositiveSmallIntegerField': 'SmallIntegerField',
         }
 
-    @cached_property
-    def is_postgresql_10(self):
-        return self.connection.pg_version >= 100000
-
     @cached_property
     def is_postgresql_11(self):
         return self.connection.pg_version >= 110000
@@ -100,10 +90,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     def is_postgresql_13(self):
         return self.connection.pg_version >= 130000
 
-    has_brin_autosummarize = property(operator.attrgetter('is_postgresql_10'))
     has_websearch_to_tsquery = property(operator.attrgetter('is_postgresql_11'))
-    supports_table_partitions = property(operator.attrgetter('is_postgresql_10'))
     supports_covering_indexes = property(operator.attrgetter('is_postgresql_11'))
     supports_covering_gist_indexes = property(operator.attrgetter('is_postgresql_12'))
     supports_non_deterministic_collations = property(operator.attrgetter('is_postgresql_12'))
-    supports_alternate_collation_providers = property(operator.attrgetter('is_postgresql_10'))

+ 2 - 2
django/db/backends/postgresql/introspection.py

@@ -48,13 +48,13 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
         """Return a list of table and view names in the current database."""
         cursor.execute("""
             SELECT c.relname,
-            CASE WHEN {} THEN 'p' WHEN c.relkind IN ('m', 'v') THEN 'v' ELSE 't' END
+            CASE WHEN c.relispartition THEN 'p' WHEN c.relkind IN ('m', 'v') THEN 'v' ELSE 't' END
             FROM pg_catalog.pg_class c
             LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
             WHERE c.relkind IN ('f', 'm', 'p', 'r', 'v')
                 AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                 AND pg_catalog.pg_table_is_visible(c.oid)
-        """.format('c.relispartition' if self.connection.features.supports_table_partitions else 'FALSE'))
+        """)
         return [TableInfo(*row) for row in cursor.fetchall() if row[0] not in self.ignored_tables]
 
     def get_table_description(self, cursor, table_name):

+ 1 - 2
docs/ref/contrib/gis/install/geolibs.txt

@@ -12,7 +12,7 @@ Program                   Description                           Required
 `PROJ`_                   Cartographic Projections library      Yes (PostgreSQL and SQLite only)  6.x, 5.x, 4.x
 :doc:`GDAL <../gdal>`     Geospatial Data Abstraction Library   Yes                               3.1, 3.0, 2.4, 2.3, 2.2, 2.1, 2.0
 :doc:`GeoIP <../geoip2>`  IP-based geolocation library          No                                2
-`PostGIS`__               Spatial extensions for PostgreSQL     Yes (PostgreSQL only)             3.0, 2.5, 2.4, 2.3
+`PostGIS`__               Spatial extensions for PostgreSQL     Yes (PostgreSQL only)             3.0, 2.5, 2.4
 `SpatiaLite`__            Spatial extensions for SQLite         Yes (SQLite only)                 4.3
 ========================  ====================================  ================================  ===================================
 
@@ -32,7 +32,6 @@ totally fine with GeoDjango. Your mileage may vary.
     GDAL 2.4.0 2018-12
     GDAL 3.0.0 2019-05
     GDAL 3.1.0 2020-05-07
-    PostGIS 2.3.0 2016-09-26
     PostGIS 2.4.0 2017-09-30
     PostGIS 2.5.0 2018-09-23
     PostGIS 3.0.0 2019-10-20

+ 7 - 7
docs/ref/contrib/gis/install/index.txt

@@ -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, PostGIS       9.6+                Requires PostGIS.
+PostgreSQL          GEOS, GDAL, PROJ, PostGIS       10+                 Requires PostGIS.
 MySQL               GEOS, GDAL                      5.7+                :ref:`Limited functionality <mysql-spatial-limitations>`.
 Oracle              GEOS, GDAL                      12.2+               XE not supported.
 SQLite              GEOS, GDAL, PROJ, SpatiaLite    3.9.0+              Requires SpatiaLite 4.3+
@@ -347,11 +347,11 @@ running macOS.  Because MacPorts still builds the software from source,
 
 Summary::
 
-    $ sudo port install postgresql93-server
+    $ sudo port install postgresql13-server
     $ sudo port install geos
-    $ sudo port install proj
-    $ sudo port install postgis
-    $ sudo port install gdal +geos
+    $ sudo port install proj6
+    $ sudo port install postgis3
+    $ sudo port install gdal
     $ sudo port install libgeoip
 
 .. note::
@@ -359,12 +359,12 @@ Summary::
     You will also have to modify the ``PATH`` in your ``.profile`` so
     that the MacPorts programs are accessible from the command-line::
 
-        export PATH=/opt/local/bin:/opt/local/lib/postgresql93/bin
+        export PATH=/opt/local/bin:/opt/local/lib/postgresql13/bin
 
     In addition, add the ``DYLD_FALLBACK_LIBRARY_PATH`` setting so that
     the libraries can be found by Python::
 
-        export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib:/opt/local/lib/postgresql93
+        export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib:/opt/local/lib/postgresql13
 
 __ https://www.macports.org/
 

+ 4 - 4
docs/ref/contrib/gis/install/postgis.txt

@@ -66,10 +66,10 @@ Managing the database
 ---------------------
 
 To administer the database, you can either use the pgAdmin III program
-(:menuselection:`Start --> PostgreSQL 9.x --> pgAdmin III`) or the
-SQL Shell (:menuselection:`Start --> PostgreSQL 9.x --> SQL Shell`).
-For example, to create a ``geodjango`` spatial database and user, the following
-may be executed from the SQL Shell as the ``postgres`` user::
+(:menuselection:`Start --> PostgreSQL X --> pgAdmin III`) or the SQL Shell
+(:menuselection:`Start --> PostgreSQL X --> SQL Shell`). For example, to create
+a ``geodjango`` spatial database and user, the following may be executed from
+the SQL Shell as the ``postgres`` user::
 
     postgres# CREATE USER geodjango PASSWORD 'my_passwd';
     postgres# CREATE DATABASE geodjango OWNER geodjango;

+ 0 - 2
docs/ref/contrib/postgres/operations.txt

@@ -159,8 +159,6 @@ For example, to create a collation for German phone book ordering::
 
 .. admonition:: Restrictions
 
-    PostgreSQL 9.6 only supports the ``'libc'`` provider.
-
     Non-deterministic collations are supported only on PostgreSQL 12+.
 
 Concurrent index operations

+ 1 - 1
docs/ref/databases.txt

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

+ 3 - 3
docs/ref/unicode.txt

@@ -18,8 +18,8 @@ able to store certain characters in the database, and information will be lost.
 * MySQL users, refer to the `MySQL manual`_ for details on how to set or alter
   the database character set encoding.
 
-* PostgreSQL users, refer to the `PostgreSQL manual`_ (section 22.3.2 in
-  PostgreSQL 9) for details on creating databases with the correct encoding.
+* PostgreSQL users, refer to the `PostgreSQL manual`_ for details on creating
+  databases with the correct encoding.
 
 * Oracle users, refer to the `Oracle manual`_ for details on how to set
   (`section 2`_) or alter (`section 11`_) the database character set encoding.
@@ -28,7 +28,7 @@ able to store certain characters in the database, and information will be lost.
   for internal encoding.
 
 .. _MySQL manual: https://dev.mysql.com/doc/refman/en/charset-database.html
-.. _PostgreSQL manual: https://www.postgresql.org/docs/current/multibyte.html
+.. _PostgreSQL manual: https://www.postgresql.org/docs/current/multibyte.html#id-1.6.10.5.6
 .. _Oracle manual: https://docs.oracle.com/en/database/oracle/oracle-database/18/nlspg/index.html
 .. _section 2: https://docs.oracle.com/en/database/oracle/oracle-database/18/nlspg/choosing-character-set.html
 .. _section 11: https://docs.oracle.com/en/database/oracle/oracle-database/18/nlspg/character-set-migration.html

+ 11 - 0
docs/releases/4.0.txt

@@ -224,6 +224,17 @@ backends.
 
 * ...
 
+:mod:`django.contrib.gis`
+-------------------------
+
+* Support for PostGIS 2.3 is removed.
+
+Dropped support for PostgreSQL 9.6
+----------------------------------
+
+Upstream support for PostgreSQL 9.6 ends in November 2021. Django 4.0 supports
+PostgreSQL 10 and higher.
+
 Miscellaneous
 -------------
 

+ 0 - 1
tests/inspectdb/tests.py

@@ -399,7 +399,6 @@ class InspectDBTransactionalTests(TransactionTestCase):
                 cursor.execute('DROP MATERIALIZED VIEW inspectdb_people_materialized')
 
     @skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific SQL')
-    @skipUnlessDBFeature('supports_table_partitions')
     def test_include_partitions(self):
         """inspectdb --include-partitions creates models for partitions."""
         with connection.cursor() as cursor:

+ 0 - 10
tests/postgres_tests/test_indexes.py

@@ -345,7 +345,6 @@ class SchemaTests(PostgreSQLTestCase):
             editor.remove_index(CharFieldModel, index)
         self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
 
-    @skipUnlessDBFeature('has_brin_autosummarize')
     def test_brin_parameters(self):
         index_name = 'char_field_brin_params'
         index = BrinIndex(fields=['field'], name=index_name, autosummarize=True)
@@ -358,15 +357,6 @@ class SchemaTests(PostgreSQLTestCase):
             editor.remove_index(CharFieldModel, index)
         self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
 
-    def test_brin_autosummarize_not_supported(self):
-        index_name = 'brin_options_exception'
-        index = BrinIndex(fields=['field'], name=index_name, autosummarize=True)
-        with self.assertRaisesMessage(NotSupportedError, 'BRIN option autosummarize requires PostgreSQL 10+.'):
-            with mock.patch('django.db.backends.postgresql.features.DatabaseFeatures.has_brin_autosummarize', False):
-                with connection.schema_editor() as editor:
-                    editor.add_index(CharFieldModel, index)
-        self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
-
     def test_btree_index(self):
         # Ensure the table is there and doesn't have an index.
         self.assertNotIn('field', self.get_constraints(CharFieldModel._meta.db_table))

+ 0 - 19
tests/postgres_tests/test_operations.py

@@ -298,7 +298,6 @@ class CreateCollationTests(PostgreSQLTestCase):
             'deterministic': False,
         })
 
-    @skipUnlessDBFeature('supports_alternate_collation_providers')
     def test_create_collation_alternate_provider(self):
         operation = CreateCollation(
             'german_phonebook_test',
@@ -339,24 +338,6 @@ class CreateCollationTests(PostgreSQLTestCase):
                 with self.assertRaisesMessage(NotSupportedError, msg):
                     operation.database_forwards(self.app_label, editor, project_state, new_state)
 
-    def test_collation_with_icu_provider_raises_error(self):
-        operation = CreateCollation(
-            'german_phonebook',
-            provider='icu',
-            locale='de-u-co-phonebk',
-        )
-        project_state = ProjectState()
-        new_state = project_state.clone()
-        msg = 'Non-libc providers require PostgreSQL 10+.'
-        with connection.schema_editor(atomic=False) as editor:
-            with mock.patch(
-                'django.db.backends.postgresql.features.DatabaseFeatures.'
-                'supports_alternate_collation_providers',
-                False,
-            ):
-                with self.assertRaisesMessage(NotSupportedError, msg):
-                    operation.database_forwards(self.app_label, editor, project_state, new_state)
-
 
 @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific tests.')
 class RemoveCollationTests(PostgreSQLTestCase):

+ 1 - 2
tests/queries/test_explain.py

@@ -52,9 +52,8 @@ class ExplainTests(TestCase):
             {'costs': False, 'buffers': True, 'analyze': True},
             {'verbose': True, 'timing': True, 'analyze': True},
             {'verbose': False, 'timing': False, 'analyze': True},
+            {'summary': True},
         ]
-        if connection.features.is_postgresql_10:
-            test_options.append({'summary': True})
         if connection.features.is_postgresql_12:
             test_options.append({'settings': True})
         if connection.features.is_postgresql_13: