diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py index efb9413119..ceb034f03e 100644 --- a/django/db/backends/sqlite3/features.py +++ b/django/db/backends/sqlite3/features.py @@ -4,6 +4,8 @@ from django.db import utils from django.db.backends.base.features import BaseDatabaseFeatures from django.utils.functional import cached_property +from .base import Database + class DatabaseFeatures(BaseDatabaseFeatures): # SQLite can read from a cursor since SQLite 3.6.5, subject to the caveat @@ -32,6 +34,8 @@ class DatabaseFeatures(BaseDatabaseFeatures): supports_cast_with_precision = False time_cast_precision = 3 can_release_savepoints = True + # Is "ALTER TABLE ... RENAME COLUMN" supported? + can_alter_table_rename_column = Database.sqlite_version_info >= (3, 25, 0) @cached_property def supports_stddev(self): diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index 8710e9d0e2..99382d35ce 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -331,6 +331,14 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): def _alter_field(self, model, old_field, new_field, old_type, new_type, old_db_params, new_db_params, strict=False): """Perform a "physical" (non-ManyToMany) field update.""" + # Use "ALTER TABLE ... RENAME COLUMN" if only the column name + # changed and there aren't any constraints. + if (self.connection.features.can_alter_table_rename_column and + old_field.column != new_field.column and + self.column_sql(model, old_field) == self.column_sql(model, new_field) and + not (old_field.remote_field and old_field.db_constraint or + new_field.remote_field and new_field.db_constraint)): + return self.execute(self._rename_field_sql(model._meta.db_table, old_field, new_field, new_type)) # Alter by remaking table self._remake_table(model, alter_field=(old_field, new_field)) # Rebuild tables with FKs pointing to this field if the PK type changed.