mirror of https://github.com/django/django.git
Fixed #34027 -- Fixed migrations crash when altering type of char/text fields referenced by foreign key on PostgreSQL.
This commit is contained in:
parent
50096a3a7a
commit
9f8c994851
|
@ -131,6 +131,20 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|||
return ""
|
||||
|
||||
def _alter_column_type_sql(self, model, old_field, new_field, new_type):
|
||||
# Drop indexes on varchar/text/citext columns that are changing to a
|
||||
# different type.
|
||||
old_db_params = old_field.db_parameters(connection=self.connection)
|
||||
old_type = old_db_params["type"]
|
||||
if (old_field.db_index or old_field.unique) and (
|
||||
(old_type.startswith("varchar") and not new_type.startswith("varchar"))
|
||||
or (old_type.startswith("text") and not new_type.startswith("text"))
|
||||
or (old_type.startswith("citext") and not new_type.startswith("citext"))
|
||||
):
|
||||
index_name = self._create_index_name(
|
||||
model._meta.db_table, [old_field.column], suffix="_like"
|
||||
)
|
||||
self.execute(self._delete_index_sql(model, index_name))
|
||||
|
||||
self.sql_alter_column_type = "ALTER COLUMN %(column)s TYPE %(type)s"
|
||||
# Cast when data type changed.
|
||||
if using_sql := self._using_sql(new_field, old_field):
|
||||
|
@ -227,18 +241,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|||
new_db_params,
|
||||
strict=False,
|
||||
):
|
||||
# Drop indexes on varchar/text/citext columns that are changing to a
|
||||
# different type.
|
||||
if (old_field.db_index or old_field.unique) and (
|
||||
(old_type.startswith("varchar") and not new_type.startswith("varchar"))
|
||||
or (old_type.startswith("text") and not new_type.startswith("text"))
|
||||
or (old_type.startswith("citext") and not new_type.startswith("citext"))
|
||||
):
|
||||
index_name = self._create_index_name(
|
||||
model._meta.db_table, [old_field.column], suffix="_like"
|
||||
)
|
||||
self.execute(self._delete_index_sql(model, index_name))
|
||||
|
||||
super()._alter_field(
|
||||
model,
|
||||
old_field,
|
||||
|
|
|
@ -2436,6 +2436,45 @@ class OperationTests(OperationTestBase):
|
|||
],
|
||||
)
|
||||
|
||||
def test_alter_field_pk_fk_char_to_int(self):
|
||||
app_label = "alter_field_pk_fk_char_to_int"
|
||||
project_state = self.apply_operations(
|
||||
app_label,
|
||||
ProjectState(),
|
||||
operations=[
|
||||
migrations.CreateModel(
|
||||
name="Parent",
|
||||
fields=[
|
||||
("id", models.CharField(max_length=255, primary_key=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Child",
|
||||
fields=[
|
||||
("id", models.BigAutoField(primary_key=True)),
|
||||
(
|
||||
"parent",
|
||||
models.ForeignKey(
|
||||
f"{app_label}.Parent",
|
||||
on_delete=models.CASCADE,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
self.apply_operations(
|
||||
app_label,
|
||||
project_state,
|
||||
operations=[
|
||||
migrations.AlterField(
|
||||
model_name="parent",
|
||||
name="id",
|
||||
field=models.BigIntegerField(primary_key=True),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
def test_rename_field_reloads_state_on_fk_target_changes(self):
|
||||
"""
|
||||
If RenameField doesn't reload state appropriately, the AlterField
|
||||
|
|
Loading…
Reference in New Issue