diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py index 143ee1e98b..4fa6ab831b 100644 --- a/django/db/backends/sqlite3/features.py +++ b/django/db/backends/sqlite3/features.py @@ -10,7 +10,7 @@ from .base import Database class DatabaseFeatures(BaseDatabaseFeatures): - minimum_database_version = (3, 31) + minimum_database_version = (3, 37) test_db_allows_multiple_connections = False supports_unspecified_pk = True supports_timezones = False @@ -26,8 +26,6 @@ class DatabaseFeatures(BaseDatabaseFeatures): time_cast_precision = 3 can_release_savepoints = True has_case_insensitive_like = True - # Is "ALTER TABLE ... DROP COLUMN" supported? - can_alter_table_drop_column = Database.sqlite_version_info >= (3, 35, 5) supports_parentheses_in_compound = False can_defer_constraint_checks = True supports_over_clause = True @@ -57,6 +55,9 @@ class DatabaseFeatures(BaseDatabaseFeatures): insert_test_table_with_defaults = 'INSERT INTO {} ("null") VALUES (1)' supports_default_keyword_in_insert = False supports_unlimited_charfield = True + can_return_columns_from_insert = True + can_return_rows_from_bulk_insert = True + can_return_rows_from_update = True @cached_property def django_test_skips(self): @@ -146,8 +147,8 @@ class DatabaseFeatures(BaseDatabaseFeatures): """ SQLite has a variable limit per query. The limit can be changed using the SQLITE_MAX_VARIABLE_NUMBER compile-time option (which defaults to - 999 in versions < 3.32.0 or 32766 in newer versions) or lowered per - connection at run-time with setlimit(SQLITE_LIMIT_VARIABLE_NUMBER, N). + 32766) or lowered per connection at run-time with + setlimit(SQLITE_LIMIT_VARIABLE_NUMBER, N). """ return self.connection.connection.getlimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) @@ -163,15 +164,3 @@ class DatabaseFeatures(BaseDatabaseFeatures): can_introspect_json_field = property(operator.attrgetter("supports_json_field")) has_json_object_function = property(operator.attrgetter("supports_json_field")) - - @cached_property - def can_return_columns_from_insert(self): - return Database.sqlite_version_info >= (3, 35) - - can_return_rows_from_bulk_insert = property( - operator.attrgetter("can_return_columns_from_insert") - ) - - can_return_rows_from_update = property( - operator.attrgetter("can_return_columns_from_insert") - ) diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py index 0bbd6f4c59..1404c71e1e 100644 --- a/django/db/backends/sqlite3/introspection.py +++ b/django/db/backends/sqlite3/introspection.py @@ -342,8 +342,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): "PRAGMA index_list(%s)" % self.connection.ops.quote_name(table_name) ) for row in cursor.fetchall(): - # SQLite 3.8.9+ has 5 columns, however older versions only give 3 - # columns. Discard last 2 columns if there. + # Discard last 2 columns. number, index, unique = row[:3] cursor.execute( "SELECT sql FROM sqlite_master WHERE type='index' AND name=%s", diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index 223a70947b..ee6163c253 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -339,10 +339,9 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): self.delete_model(field.remote_field.through) # For explicit "through" M2M fields, do nothing elif ( - self.connection.features.can_alter_table_drop_column # Primary keys, unique fields, indexed fields, and foreign keys are # not supported in ALTER TABLE DROP COLUMN. - and not field.primary_key + not field.primary_key and not field.unique and not field.db_index and not (field.remote_field and field.db_constraint) diff --git a/docs/ref/contrib/gis/install/index.txt b/docs/ref/contrib/gis/install/index.txt index e08c78b147..f127478151 100644 --- a/docs/ref/contrib/gis/install/index.txt +++ b/docs/ref/contrib/gis/install/index.txt @@ -60,7 +60,7 @@ Database Library Requirements Supported Versions Notes PostgreSQL GEOS, GDAL, PROJ, PostGIS 15+ Requires PostGIS. MySQL GEOS, GDAL 8.0.11+ :ref:`Limited functionality `. Oracle GEOS, GDAL 19+ XE not supported. -SQLite GEOS, GDAL, PROJ, SpatiaLite 3.31.0+ Requires SpatiaLite 4.3+ +SQLite GEOS, GDAL, PROJ, SpatiaLite 3.37.0+ Requires SpatiaLite 4.3+ ================== ============================== ================== ========================================= See also `this comparison matrix`__ on the OSGeo Wiki for diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index cbd0e2feea..cd415e1c00 100644 --- a/docs/ref/databases.txt +++ b/docs/ref/databases.txt @@ -814,7 +814,7 @@ appropriate typecasting. SQLite notes ============ -Django supports SQLite 3.31.0 and later. +Django supports SQLite 3.37.0 and later. SQLite_ provides an excellent development alternative for applications that are predominantly read-only or require a smaller installation footprint. As diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 164bc9ce54..d9badb690d 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -2439,8 +2439,8 @@ This has a number of caveats though: * If the model's primary key is an :class:`~django.db.models.AutoField` or has a :attr:`~django.db.models.Field.db_default` value, and ``ignore_conflicts`` is ``False``, the primary key attribute can only be retrieved on certain - databases (currently PostgreSQL, MariaDB, and SQLite 3.35+). On other - databases, it will not be set. + databases (currently PostgreSQL, MariaDB, and SQLite). On other databases, it + will not be set. * It does not work with many-to-many relationships. * It casts ``objs`` to a list, which fully evaluates ``objs`` if it's a generator. The cast allows inspecting all objects so that any objects with a diff --git a/docs/releases/6.1.txt b/docs/releases/6.1.txt index d199423176..1430cb4f17 100644 --- a/docs/releases/6.1.txt +++ b/docs/releases/6.1.txt @@ -325,6 +325,8 @@ Miscellaneous * :class:`~django.contrib.contenttypes.fields.GenericForeignKey` now uses a separate descriptor class: the private ``GenericForeignKeyDescriptor``. +* The minimum supported version of SQLite is increased from 3.31.0 to 3.37.0. + .. _deprecated-features-6.1: Features deprecated in 6.1 diff --git a/tests/backends/sqlite/tests.py b/tests/backends/sqlite/tests.py index fafc0b182f..37d95c0cb5 100644 --- a/tests/backends/sqlite/tests.py +++ b/tests/backends/sqlite/tests.py @@ -109,9 +109,9 @@ class Tests(TestCase): connections["default"].close() self.assertTrue(os.path.isfile(os.path.join(tmp, "test.db"))) - @mock.patch.object(connection, "get_database_version", return_value=(3, 30)) + @mock.patch.object(connection, "get_database_version", return_value=(3, 36)) def test_check_database_version_supported(self, mocked_get_database_version): - msg = "SQLite 3.31 or later is required (found 3.30)." + msg = "SQLite 3.37 or later is required (found 3.36)." with self.assertRaisesMessage(NotSupportedError, msg): connection.check_database_version_supported() self.assertTrue(mocked_get_database_version.called)