Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion django/contrib/gis/db/backends/postgis/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def spatial_version(self):
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']
)
Expand Down
4 changes: 0 additions & 4 deletions django/contrib/postgres/indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@ def deconstruct(self):
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:
Expand Down
5 changes: 0 additions & 5 deletions django/contrib/postgres/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,6 @@ def create_collation(self, schema_editor):
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)
Expand Down
21 changes: 4 additions & 17 deletions django/db/backends/postgresql/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,17 @@ 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.': {
'indexes.tests.SchemaIndexesNotPostgreSQLTests.test_create_index_ignores_opclasses',
},
}

@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 {
Expand All @@ -84,10 +78,6 @@ def introspected_field_types(self):
'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
Expand All @@ -100,10 +90,7 @@ def is_postgresql_12(self):
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'))
4 changes: 2 additions & 2 deletions django/db/backends/postgresql/introspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ def get_table_list(self, cursor):
"""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):
Expand Down
3 changes: 1 addition & 2 deletions docs/ref/contrib/gis/install/geolibs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
======================== ==================================== ================================ ===================================

Expand All @@ -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
Expand Down
14 changes: 7 additions & 7 deletions docs/ref/contrib/gis/install/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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+
Expand Down Expand Up @@ -347,24 +347,24 @@ 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::

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/

Expand Down
8 changes: 4 additions & 4 deletions docs/ref/contrib/gis/install/postgis.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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;
2 changes: 0 additions & 2 deletions docs/ref/contrib/postgres/operations.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion docs/ref/databases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
6 changes: 3 additions & 3 deletions docs/ref/unicode.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
11 changes: 11 additions & 0 deletions docs/releases/4.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------

Expand Down
1 change: 0 additions & 1 deletion tests/inspectdb/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ def test_include_materialized_views(self):
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:
Expand Down
10 changes: 0 additions & 10 deletions tests/postgres_tests/test_indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ def test_brin_index(self):
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)
Expand All @@ -358,15 +357,6 @@ def test_brin_parameters(self):
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))
Expand Down
19 changes: 0 additions & 19 deletions tests/postgres_tests/test_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,6 @@ def test_create_non_deterministic_collation(self):
'deterministic': False,
})

@skipUnlessDBFeature('supports_alternate_collation_providers')
def test_create_collation_alternate_provider(self):
operation = CreateCollation(
'german_phonebook_test',
Expand Down Expand Up @@ -339,24 +338,6 @@ def test_nondeterministic_collation_not_supported(self):
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):
Expand Down
3 changes: 1 addition & 2 deletions tests/queries/test_explain.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ def test_postgres_options(self):
{'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:
Expand Down