summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/gis/db/backends/postgis/operations.py2
-rw-r--r--django/contrib/postgres/indexes.py4
-rw-r--r--django/contrib/postgres/operations.py5
-rw-r--r--django/db/backends/postgresql/features.py21
-rw-r--r--django/db/backends/postgresql/introspection.py4
-rw-r--r--docs/ref/contrib/gis/install/geolibs.txt3
-rw-r--r--docs/ref/contrib/gis/install/index.txt14
-rw-r--r--docs/ref/contrib/gis/install/postgis.txt8
-rw-r--r--docs/ref/contrib/postgres/operations.txt2
-rw-r--r--docs/ref/databases.txt2
-rw-r--r--docs/ref/unicode.txt6
-rw-r--r--docs/releases/4.0.txt11
-rw-r--r--tests/inspectdb/tests.py1
-rw-r--r--tests/postgres_tests/test_indexes.py10
-rw-r--r--tests/postgres_tests/test_operations.py19
-rw-r--r--tests/queries/test_explain.py3
16 files changed, 35 insertions, 80 deletions
diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py
index f068f28f48..84110fce0f 100644
--- a/django/contrib/gis/db/backends/postgis/operations.py
+++ b/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']
)
diff --git a/django/contrib/postgres/indexes.py b/django/contrib/postgres/indexes.py
index af9de758f7..2642164aa1 100644
--- a/django/contrib/postgres/indexes.py
+++ b/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:
diff --git a/django/contrib/postgres/operations.py b/django/contrib/postgres/operations.py
index a8092ec362..e5f2b9e92f 100644
--- a/django/contrib/postgres/operations.py
+++ b/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)
diff --git a/django/db/backends/postgresql/features.py b/django/db/backends/postgresql/features.py
index 84259c0c19..722bfe0475 100644
--- a/django/db/backends/postgresql/features.py
+++ b/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.': {
@@ -66,16 +70,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 {
**super().introspected_field_types,
@@ -85,10 +79,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
}
@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'))
diff --git a/django/db/backends/postgresql/introspection.py b/django/db/backends/postgresql/introspection.py
index a0e49c8da7..4e35cb9e97 100644
--- a/django/db/backends/postgresql/introspection.py
+++ b/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):
diff --git a/docs/ref/contrib/gis/install/geolibs.txt b/docs/ref/contrib/gis/install/geolibs.txt
index 74f17d886a..405150bc29 100644
--- a/docs/ref/contrib/gis/install/geolibs.txt
+++ b/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
diff --git a/docs/ref/contrib/gis/install/index.txt b/docs/ref/contrib/gis/install/index.txt
index c8343913cf..cc72a8dc2b 100644
--- a/docs/ref/contrib/gis/install/index.txt
+++ b/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/
diff --git a/docs/ref/contrib/gis/install/postgis.txt b/docs/ref/contrib/gis/install/postgis.txt
index ec56397a60..c769dcf05c 100644
--- a/docs/ref/contrib/gis/install/postgis.txt
+++ b/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;
diff --git a/docs/ref/contrib/postgres/operations.txt b/docs/ref/contrib/postgres/operations.txt
index 8491ac2f52..dc9faebcdb 100644
--- a/docs/ref/contrib/postgres/operations.txt
+++ b/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
diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt
index 8fc9e89662..a9edf43c54 100644
--- a/docs/ref/databases.txt
+++ b/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/
diff --git a/docs/ref/unicode.txt b/docs/ref/unicode.txt
index e980147f49..209cd68060 100644
--- a/docs/ref/unicode.txt
+++ b/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
diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt
index ed991fb672..9141a4eeaf 100644
--- a/docs/releases/4.0.txt
+++ b/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
-------------
diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py
index a0c4aff2e5..8be1681106 100644
--- a/tests/inspectdb/tests.py
+++ b/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:
diff --git a/tests/postgres_tests/test_indexes.py b/tests/postgres_tests/test_indexes.py
index 49646feb97..a212de2087 100644
--- a/tests/postgres_tests/test_indexes.py
+++ b/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))
diff --git a/tests/postgres_tests/test_operations.py b/tests/postgres_tests/test_operations.py
index b914a70523..9faf938c55 100644
--- a/tests/postgres_tests/test_operations.py
+++ b/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):
diff --git a/tests/queries/test_explain.py b/tests/queries/test_explain.py
index ba835afb74..4a22656657 100644
--- a/tests/queries/test_explain.py
+++ b/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: