From 3b09f3555859495ca0d130712d240fb61493739e Mon Sep 17 00:00:00 2001 From: nabil-rady Date: Wed, 15 Feb 2023 13:43:51 +0200 Subject: [PATCH] [4.2.x] Fixed #34320 -- Make sure constraints names are obtained from truncated columns names. Backport of 6bdc3c58b65eb32fd63cd41849f00a17a36b4473 from main --- django/db/backends/base/schema.py | 8 ++++++-- tests/schema/tests.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py index 3a83e14be9..070211f6d2 100644 --- a/django/db/backends/base/schema.py +++ b/django/db/backends/base/schema.py @@ -11,7 +11,7 @@ from django.db.backends.ddl_references import ( Statement, Table, ) -from django.db.backends.utils import names_digest, split_identifier +from django.db.backends.utils import names_digest, split_identifier, truncate_name from django.db.models import Deferrable, Index from django.db.models.sql import Query from django.db.transaction import TransactionManagementError, atomic @@ -1760,7 +1760,11 @@ class BaseDatabaseSchemaEditor: """Return all constraint names matching the columns and conditions.""" if column_names is not None: column_names = [ - self.connection.introspection.identifier_converter(name) + self.connection.introspection.identifier_converter( + truncate_name(name, self.connection.ops.max_name_length()) + ) + if self.connection.features.truncates_names + else self.connection.introspection.identifier_converter(name) for name in column_names ] with self.connection.cursor() as cursor: diff --git a/tests/schema/tests.py b/tests/schema/tests.py index bc603cb772..836b02f07f 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -13,6 +13,7 @@ from django.db import ( OperationalError, connection, ) +from django.db.backends.utils import truncate_name from django.db.models import ( CASCADE, PROTECT, @@ -2072,6 +2073,36 @@ class SchemaTests(TransactionTestCase): with self.assertRaises(IntegrityError): NoteRename.objects.create(detail_info=None) + @isolate_apps("schema") + def test_rename_field_with_check_to_truncated_name(self): + class AuthorWithLongColumn(Model): + field_with_very_looooooong_name = PositiveIntegerField(null=True) + + class Meta: + app_label = "schema" + + self.isolated_local_models = [AuthorWithLongColumn] + with connection.schema_editor() as editor: + editor.create_model(AuthorWithLongColumn) + old_field = AuthorWithLongColumn._meta.get_field( + "field_with_very_looooooong_name" + ) + new_field = PositiveIntegerField(null=True) + new_field.set_attributes_from_name("renamed_field_with_very_long_name") + with connection.schema_editor() as editor: + editor.alter_field(AuthorWithLongColumn, old_field, new_field, strict=True) + + new_field_name = truncate_name( + new_field.column, connection.ops.max_name_length() + ) + constraints = self.get_constraints(AuthorWithLongColumn._meta.db_table) + check_constraints = [ + name + for name, details in constraints.items() + if details["columns"] == [new_field_name] and details["check"] + ] + self.assertEqual(len(check_constraints), 1) + def _test_m2m_create(self, M2MFieldClass): """ Tests M2M fields on models during creation