diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py index 91351e5c9e..cf9243ccf0 100644 --- a/django/db/backends/base/schema.py +++ b/django/db/backends/base/schema.py @@ -95,7 +95,7 @@ class BaseDatabaseSchemaEditor: sql_alter_column_default = "ALTER COLUMN %(column)s SET DEFAULT %(default)s" sql_alter_column_no_default = "ALTER COLUMN %(column)s DROP DEFAULT" sql_alter_column_no_default_null = sql_alter_column_no_default - sql_delete_column = "ALTER TABLE %(table)s DROP COLUMN %(column)s CASCADE" + sql_delete_column = "ALTER TABLE %(table)s DROP COLUMN %(column)s" sql_rename_column = ( "ALTER TABLE %(table)s RENAME COLUMN %(old_column)s TO %(new_column)s" ) diff --git a/django/db/backends/mysql/schema.py b/django/db/backends/mysql/schema.py index 002ed20700..a4dba0ad39 100644 --- a/django/db/backends/mysql/schema.py +++ b/django/db/backends/mysql/schema.py @@ -11,9 +11,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): sql_alter_column_type = "MODIFY %(column)s %(type)s%(collation)s%(comment)s" sql_alter_column_no_default_null = "ALTER COLUMN %(column)s SET DEFAULT NULL" - # No 'CASCADE' which works as a no-op in MySQL but is undocumented - sql_delete_column = "ALTER TABLE %(table)s DROP COLUMN %(column)s" - sql_delete_unique = "ALTER TABLE %(table)s DROP INDEX %(name)s" sql_create_column_inline_fk = ( ", ADD CONSTRAINT %(name)s FOREIGN KEY (%(column)s) " diff --git a/django/db/backends/oracle/schema.py b/django/db/backends/oracle/schema.py index ba3c4778d3..f094bfb038 100644 --- a/django/db/backends/oracle/schema.py +++ b/django/db/backends/oracle/schema.py @@ -19,7 +19,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): sql_alter_column_no_default = "MODIFY %(column)s DEFAULT NULL" sql_alter_column_no_default_null = sql_alter_column_no_default - sql_delete_column = "ALTER TABLE %(table)s DROP COLUMN %(column)s" sql_create_column_inline_fk = ( "CONSTRAINT %(name)s REFERENCES %(to_table)s(%(to_column)s)%(deferrable)s" ) diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index 3617d17fac..10edfd81b9 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -16,7 +16,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): "REFERENCES %(to_table)s (%(to_column)s) DEFERRABLE INITIALLY DEFERRED" ) sql_create_column_inline_fk = sql_create_inline_fk - sql_delete_column = "ALTER TABLE %(table)s DROP COLUMN %(column)s" sql_create_unique = "CREATE UNIQUE INDEX %(name)s ON %(table)s (%(columns)s)" sql_delete_unique = "DROP INDEX %(name)s" sql_alter_table_comment = None diff --git a/docs/ref/migration-operations.txt b/docs/ref/migration-operations.txt index 8379221df5..26c0c14218 100644 --- a/docs/ref/migration-operations.txt +++ b/docs/ref/migration-operations.txt @@ -195,15 +195,12 @@ if the field is nullable or if it has a default value that can be used to populate the recreated column. If the field is not nullable and does not have a default value, the operation is irreversible. -.. admonition:: PostgreSQL - - ``RemoveField`` will also delete any additional database objects that are - related to the removed field (like views, for example). This is because the - resulting ``DROP COLUMN`` statement will include the ``CASCADE`` clause to - ensure `dependent objects outside the table are also dropped`_. - -.. _dependent objects outside the table are also dropped: https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-PARMS-CASCADE +.. versionchanged:: 6.0 + :class:`~django.db.backends.base.schema.BaseDatabaseSchemaEditor` and + PostgreSQL backends no longer use ``CASCADE`` to delete dependent related + database objects, such as views. Any dependent objects that are not managed + by Django may need to be removed manually before running ``RemoveField``. ``AlterField`` -------------- diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt index 44b9781d44..a5679dd63c 100644 --- a/docs/releases/6.0.txt +++ b/docs/releases/6.0.txt @@ -254,6 +254,9 @@ backends. * ``BaseDatabaseCreation.create_test_db(serialize)`` is deprecated. Use ``serialize_db_to_string()`` instead. +* :class:`~django.db.backends.base.schema.BaseDatabaseSchemaEditor` and + PostgreSQL backends no longer use ``CASCADE`` when dropping a column. + Dropped support for MariaDB 10.5 -------------------------------- diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index e92b1c4506..1a268a8d86 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -2055,8 +2055,13 @@ class OperationTests(OperationTestBase): self.assertEqual(len(new_state.models["test_rmfl", "pony"].fields), 4) # Test the database alteration self.assertColumnExists("test_rmfl_pony", "pink") - with connection.schema_editor() as editor: + with ( + connection.schema_editor() as editor, + CaptureQueriesContext(connection) as ctx, + ): operation.database_forwards("test_rmfl", editor, project_state, new_state) + self.assertGreater(len(ctx.captured_queries), 0) + self.assertNotIn("CASCADE", ctx.captured_queries[-1]["sql"]) self.assertColumnNotExists("test_rmfl_pony", "pink") # And test reversal with connection.schema_editor() as editor: