瀏覽代碼

Fixed #34320 -- Make sure constraints names are obtained from truncated columns names.

nabil-rady 2 年之前
父節點
當前提交
6bdc3c58b6
共有 2 個文件被更改,包括 37 次插入2 次删除
  1. 6 2
      django/db/backends/base/schema.py
  2. 31 0
      tests/schema/tests.py

+ 6 - 2
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:

+ 31 - 0
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