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 ""
|
return ""
|
||||||
|
|
||||||
def _alter_column_type_sql(self, model, old_field, new_field, new_type):
|
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"
|
self.sql_alter_column_type = "ALTER COLUMN %(column)s TYPE %(type)s"
|
||||||
# Cast when data type changed.
|
# Cast when data type changed.
|
||||||
if using_sql := self._using_sql(new_field, old_field):
|
if using_sql := self._using_sql(new_field, old_field):
|
||||||
|
@ -227,18 +241,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||||
new_db_params,
|
new_db_params,
|
||||||
strict=False,
|
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(
|
super()._alter_field(
|
||||||
model,
|
model,
|
||||||
old_field,
|
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):
|
def test_rename_field_reloads_state_on_fk_target_changes(self):
|
||||||
"""
|
"""
|
||||||
If RenameField doesn't reload state appropriately, the AlterField
|
If RenameField doesn't reload state appropriately, the AlterField
|
||||||
|
|
Loading…
Reference in New Issue