Fixed #34761 -- Dropped support for MySQL < 8.0.11.

This commit is contained in:
Mariusz Felisiak 2023-08-03 18:54:29 +02:00 committed by GitHub
parent b3e0170ab5
commit b719688b21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 35 additions and 61 deletions

View File

@ -11,6 +11,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
# MySQL doesn't support sliced subqueries with IN/ALL/ANY/SOME. # MySQL doesn't support sliced subqueries with IN/ALL/ANY/SOME.
allow_sliced_subqueries_with_in = False allow_sliced_subqueries_with_in = False
has_select_for_update = True has_select_for_update = True
has_select_for_update_nowait = True
supports_forward_references = False supports_forward_references = False
supports_regex_backreferencing = False supports_regex_backreferencing = False
supports_date_lookup_using_string = False supports_date_lookup_using_string = False
@ -23,6 +24,8 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_temporal_subtraction = True supports_temporal_subtraction = True
supports_slicing_ordering_in_compound = True supports_slicing_ordering_in_compound = True
supports_index_on_text_field = False supports_index_on_text_field = False
supports_over_clause = True
supports_frame_range_fixed_distance = True
supports_update_conflicts = True supports_update_conflicts = True
delete_can_self_reference_subquery = False delete_can_self_reference_subquery = False
create_test_procedure_without_params_sql = """ create_test_procedure_without_params_sql = """
@ -62,7 +65,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
if self.connection.mysql_is_mariadb: if self.connection.mysql_is_mariadb:
return (10, 4) return (10, 4)
else: else:
return (8,) return (8, 0, 11)
@cached_property @cached_property
def test_collations(self): def test_collations(self):
@ -225,16 +228,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
def is_sql_auto_is_null_enabled(self): def is_sql_auto_is_null_enabled(self):
return self.connection.mysql_server_data["sql_auto_is_null"] return self.connection.mysql_server_data["sql_auto_is_null"]
@cached_property
def supports_over_clause(self):
if self.connection.mysql_is_mariadb:
return True
return self.connection.mysql_version >= (8, 0, 2)
supports_frame_range_fixed_distance = property(
operator.attrgetter("supports_over_clause")
)
@cached_property @cached_property
def supports_column_check_constraints(self): def supports_column_check_constraints(self):
if self.connection.mysql_is_mariadb: if self.connection.mysql_is_mariadb:
@ -255,20 +248,11 @@ class DatabaseFeatures(BaseDatabaseFeatures):
def has_select_for_update_skip_locked(self): def has_select_for_update_skip_locked(self):
if self.connection.mysql_is_mariadb: if self.connection.mysql_is_mariadb:
return self.connection.mysql_version >= (10, 6) return self.connection.mysql_version >= (10, 6)
return self.connection.mysql_version >= (8, 0, 1) return True
@cached_property
def has_select_for_update_nowait(self):
if self.connection.mysql_is_mariadb:
return True
return self.connection.mysql_version >= (8, 0, 1)
@cached_property @cached_property
def has_select_for_update_of(self): def has_select_for_update_of(self):
return ( return not self.connection.mysql_is_mariadb
not self.connection.mysql_is_mariadb
and self.connection.mysql_version >= (8, 0, 1)
)
@cached_property @cached_property
def supports_explain_analyze(self): def supports_explain_analyze(self):
@ -319,7 +303,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
return False return False
if self.connection.mysql_is_mariadb: if self.connection.mysql_is_mariadb:
return self.connection.mysql_version >= (10, 8) return self.connection.mysql_version >= (10, 8)
return self.connection.mysql_version >= (8, 0, 1) return True
@cached_property @cached_property
def supports_expression_indexes(self): def supports_expression_indexes(self):

View File

@ -45,14 +45,12 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
@property @property
def sql_rename_column(self): def sql_rename_column(self):
# MariaDB >= 10.5.2 and MySQL >= 8.0.4 support an is_mariadb = self.connection.mysql_is_mariadb
# "ALTER TABLE ... RENAME COLUMN" statement. if is_mariadb and self.connection.mysql_version < (10, 5, 2):
if self.connection.mysql_is_mariadb: # MariaDB < 10.5.2 doesn't support an
if self.connection.mysql_version >= (10, 5, 2): # "ALTER TABLE ... RENAME COLUMN" statement.
return super().sql_rename_column return "ALTER TABLE %(table)s CHANGE %(old_column)s %(new_column)s %(type)s"
elif self.connection.mysql_version >= (8, 0, 4): return super().sql_rename_column
return super().sql_rename_column
return "ALTER TABLE %(table)s CHANGE %(old_column)s %(new_column)s %(type)s"
def quote_value(self, value): def quote_value(self, value):
self.connection.ensure_connection() self.connection.ensure_connection()

View File

@ -57,7 +57,7 @@ supported versions, and any notes for each of the supported database backends:
Database Library Requirements Supported Versions Notes Database Library Requirements Supported Versions Notes
================== ============================== ================== ========================================= ================== ============================== ================== =========================================
PostgreSQL GEOS, GDAL, PROJ, PostGIS 12+ Requires PostGIS. PostgreSQL GEOS, GDAL, PROJ, PostGIS 12+ Requires PostGIS.
MySQL GEOS, GDAL 8+ :ref:`Limited functionality <mysql-spatial-limitations>`. MySQL GEOS, GDAL 8.0.11+ :ref:`Limited functionality <mysql-spatial-limitations>`.
Oracle GEOS, GDAL 19+ XE not supported. Oracle GEOS, GDAL 19+ XE not supported.
SQLite GEOS, GDAL, PROJ, SpatiaLite 3.21.0+ Requires SpatiaLite 4.3+ SQLite GEOS, GDAL, PROJ, SpatiaLite 3.21.0+ Requires SpatiaLite 4.3+
================== ============================== ================== ========================================= ================== ============================== ================== =========================================

View File

@ -412,7 +412,7 @@ MySQL notes
Version support Version support
--------------- ---------------
Django supports MySQL 8 and higher. Django supports MySQL 8.0.11 and higher.
Django's ``inspectdb`` feature uses the ``information_schema`` database, which Django's ``inspectdb`` feature uses the ``information_schema`` database, which
contains detailed data on all database schemas. contains detailed data on all database schemas.
@ -755,14 +755,14 @@ MySQL and MariaDB do not support some options to the ``SELECT ... FOR UPDATE``
statement. If ``select_for_update()`` is used with an unsupported option, then statement. If ``select_for_update()`` is used with an unsupported option, then
a :exc:`~django.db.NotSupportedError` is raised. a :exc:`~django.db.NotSupportedError` is raised.
=============== ========= ========== =============== ========= =====
Option MariaDB MySQL Option MariaDB MySQL
=============== ========= ========== =============== ========= =====
``SKIP LOCKED`` X (≥10.6) X (≥8.0.1) ``SKIP LOCKED`` X (≥10.6) X
``NOWAIT`` X X (≥8.0.1) ``NOWAIT`` X X
``OF`` X (≥8.0.1) ``OF`` X
``NO KEY`` ``NO KEY``
=============== ========= ========== =============== ========= =====
When using ``select_for_update()`` on MySQL, make sure you filter a queryset When using ``select_for_update()`` on MySQL, make sure you filter a queryset
against at least a set of fields contained in unique constraints or only against at least a set of fields contained in unique constraints or only

View File

@ -880,7 +880,7 @@ from groups to be included:
Support for filtering against window functions was added. Support for filtering against window functions was added.
Among Django's built-in database backends, MySQL 8.0.2+, PostgreSQL, and Oracle Among Django's built-in database backends, MySQL, PostgreSQL, and Oracle
support window expressions. Support for different window expression features support window expressions. Support for different window expression features
varies among the different databases. For example, the options in varies among the different databases. For example, the options in
:meth:`~django.db.models.Expression.asc` and :meth:`~django.db.models.Expression.asc` and

View File

@ -82,10 +82,10 @@ field's name.
For example ``Index(fields=['headline', '-pub_date'])`` would create SQL with For example ``Index(fields=['headline', '-pub_date'])`` would create SQL with
``(headline, pub_date DESC)``. ``(headline, pub_date DESC)``.
.. admonition:: MySQL and MariaDB .. admonition:: MariaDB
Index ordering isn't supported on MySQL < 8.0.1 and MariaDB < 10.8. In that Index ordering isn't supported on MariaDB < 10.8. In that case, a
case, a descending index is created as a normal index. descending index is created as a normal index.
``name`` ``name``
-------- --------

View File

@ -1928,8 +1928,8 @@ them:
The ``postgresql``, ``oracle``, and ``mysql`` database backends support The ``postgresql``, ``oracle``, and ``mysql`` database backends support
``select_for_update()``. However, MariaDB only supports the ``nowait`` ``select_for_update()``. However, MariaDB only supports the ``nowait``
argument, MariaDB 10.6+ also supports the ``skip_locked`` argument, and MySQL argument, MariaDB 10.6+ also supports the ``skip_locked`` argument, and MySQL
8.0.1+ supports the ``nowait``, ``skip_locked``, and ``of`` arguments. The supports the ``nowait``, ``skip_locked``, and ``of`` arguments. The ``no_key``
``no_key`` argument is only supported on PostgreSQL. argument is only supported on PostgreSQL.
Passing ``nowait=True``, ``skip_locked=True``, ``no_key=True``, or ``of`` to Passing ``nowait=True``, ``skip_locked=True``, ``no_key=True``, or ``of`` to
``select_for_update()`` using database backends that do not support these ``select_for_update()`` using database backends that do not support these

View File

@ -463,6 +463,12 @@ backends.
``False`` if the database doesn't support the ``DEFAULT`` keyword in bulk ``False`` if the database doesn't support the ``DEFAULT`` keyword in bulk
``INSERT`` queries. ``INSERT`` queries.
Dropped support for MySQL < 8.0.11
----------------------------------
Support for pre-releases of MySQL 8.0.x series is removed. Django 5.0 supports
MySQL 8.0.11 and higher.
:mod:`django.contrib.gis` :mod:`django.contrib.gis`
------------------------- -------------------------

View File

@ -23,20 +23,6 @@ class TestFeatures(TestCase):
self.assertFalse(connection.features.supports_transactions) self.assertFalse(connection.features.supports_transactions)
del connection.features.supports_transactions del connection.features.supports_transactions
def test_skip_locked_no_wait(self):
with mock.MagicMock() as _connection:
_connection.mysql_version = (8, 0, 1)
_connection.mysql_is_mariadb = False
database_features = DatabaseFeatures(_connection)
self.assertTrue(database_features.has_select_for_update_skip_locked)
self.assertTrue(database_features.has_select_for_update_nowait)
with mock.MagicMock() as _connection:
_connection.mysql_version = (8, 0, 0)
_connection.mysql_is_mariadb = False
database_features = DatabaseFeatures(_connection)
self.assertFalse(database_features.has_select_for_update_skip_locked)
self.assertFalse(database_features.has_select_for_update_nowait)
def test_allows_auto_pk_0(self): def test_allows_auto_pk_0(self):
with mock.MagicMock() as _connection: with mock.MagicMock() as _connection:
_connection.sql_mode = {"NO_AUTO_VALUE_ON_ZERO"} _connection.sql_mode = {"NO_AUTO_VALUE_ON_ZERO"}

View File

@ -109,8 +109,8 @@ class Tests(TestCase):
mocked_get_database_version.return_value = (10, 3) mocked_get_database_version.return_value = (10, 3)
msg = "MariaDB 10.4 or later is required (found 10.3)." msg = "MariaDB 10.4 or later is required (found 10.3)."
else: else:
mocked_get_database_version.return_value = (5, 7) mocked_get_database_version.return_value = (8, 0, 4)
msg = "MySQL 8 or later is required (found 5.7)." msg = "MySQL 8.0.11 or later is required (found 8.0.4)."
with self.assertRaisesMessage(NotSupportedError, msg): with self.assertRaisesMessage(NotSupportedError, msg):
connection.check_database_version_supported() connection.check_database_version_supported()