Fixed #34058 -- Changed sequence types when altering pre-Django 4.1 auto fields on PostgreSQL.
Thanks Anders Kaseorg for the report.
Thanks Florian Apolloner for pair programming.
Regression in 2eea361eff
.
This commit is contained in:
parent
468d061097
commit
19e6efa50b
|
@ -13,7 +13,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||||
"UPDATE %(table)s SET %(column)s = %(default)s WHERE %(column)s IS NULL"
|
"UPDATE %(table)s SET %(column)s = %(default)s WHERE %(column)s IS NULL"
|
||||||
"; SET CONSTRAINTS ALL IMMEDIATE"
|
"; SET CONSTRAINTS ALL IMMEDIATE"
|
||||||
)
|
)
|
||||||
|
sql_alter_sequence_type = "ALTER SEQUENCE IF EXISTS %(sequence)s AS %(type)s"
|
||||||
sql_delete_sequence = "DROP SEQUENCE IF EXISTS %(sequence)s CASCADE"
|
sql_delete_sequence = "DROP SEQUENCE IF EXISTS %(sequence)s CASCADE"
|
||||||
|
|
||||||
sql_create_index = (
|
sql_create_index = (
|
||||||
|
@ -208,6 +208,29 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
elif new_is_auto and old_is_auto and old_internal_type != new_internal_type:
|
||||||
|
fragment, _ = super()._alter_column_type_sql(
|
||||||
|
model, old_field, new_field, new_type
|
||||||
|
)
|
||||||
|
column = strip_quotes(new_field.column)
|
||||||
|
sequence_name = f"{table}_{column}_seq"
|
||||||
|
db_types = {
|
||||||
|
"AutoField": "integer",
|
||||||
|
"BigAutoField": "bigint",
|
||||||
|
"SmallAutoField": "smallint",
|
||||||
|
}
|
||||||
|
return fragment, [
|
||||||
|
# Alter the sequence type if exists (Django 4.1+ identity
|
||||||
|
# columns don't have it).
|
||||||
|
(
|
||||||
|
self.sql_alter_sequence_type
|
||||||
|
% {
|
||||||
|
"sequence": self.quote_name(sequence_name),
|
||||||
|
"type": db_types[new_internal_type],
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
return super()._alter_column_type_sql(model, old_field, new_field, new_type)
|
return super()._alter_column_type_sql(model, old_field, new_field, new_type)
|
||||||
|
|
||||||
|
|
|
@ -35,3 +35,7 @@ Bugfixes
|
||||||
* Fixed a regression in Django 4.1 where the ``--debug-mode`` argument to
|
* Fixed a regression in Django 4.1 where the ``--debug-mode`` argument to
|
||||||
``test`` did not work when running parallel tests with the
|
``test`` did not work when running parallel tests with the
|
||||||
``multiprocessing`` start method ``spawn`` (:ticket:`34010`).
|
``multiprocessing`` start method ``spawn`` (:ticket:`34010`).
|
||||||
|
|
||||||
|
* Fixed a regression in Django 4.1 that didn't alter a sequence type when
|
||||||
|
altering type of pre-Django 4.1 serial columns on PostgreSQL
|
||||||
|
(:ticket:`34058`).
|
||||||
|
|
|
@ -1873,6 +1873,41 @@ class SchemaTests(TransactionTestCase):
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor:
|
||||||
editor.alter_field(SmallIntegerPK, old_field, new_field, strict=True)
|
editor.alter_field(SmallIntegerPK, old_field, new_field, strict=True)
|
||||||
|
|
||||||
|
@isolate_apps("schema")
|
||||||
|
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
|
||||||
|
def test_alter_serial_auto_field_to_bigautofield(self):
|
||||||
|
class SerialAutoField(Model):
|
||||||
|
id = SmallAutoField(primary_key=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = "schema"
|
||||||
|
|
||||||
|
table = SerialAutoField._meta.db_table
|
||||||
|
column = SerialAutoField._meta.get_field("id").column
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
f'CREATE TABLE "{table}" '
|
||||||
|
f'("{column}" smallserial NOT NULL PRIMARY KEY)'
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
old_field = SerialAutoField._meta.get_field("id")
|
||||||
|
new_field = BigAutoField(primary_key=True)
|
||||||
|
new_field.model = SerialAutoField
|
||||||
|
new_field.set_attributes_from_name("id")
|
||||||
|
with connection.schema_editor() as editor:
|
||||||
|
editor.alter_field(SerialAutoField, old_field, new_field, strict=True)
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
"SELECT data_type FROM pg_sequences WHERE sequencename = %s",
|
||||||
|
[f"{table}_{column}_seq"],
|
||||||
|
)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
sequence_data_type = row[0] if row and row[0] else None
|
||||||
|
self.assertEqual(sequence_data_type, "bigint")
|
||||||
|
finally:
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute(f'DROP TABLE "{table}"')
|
||||||
|
|
||||||
def test_alter_int_pk_to_int_unique(self):
|
def test_alter_int_pk_to_int_unique(self):
|
||||||
"""
|
"""
|
||||||
Should be able to rename an IntegerField(primary_key=True) to
|
Should be able to rename an IntegerField(primary_key=True) to
|
||||||
|
|
Loading…
Reference in New Issue