mirror of
https://github.com/django/django.git
synced 2025-04-12 11:32:20 +00:00
[4.1.x] 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 2eea361eff58dd98c409c5227064b901f41bd0d6. Backport of 19e6efa50b603af325e7f62058364f278596758f from main
This commit is contained in:
parent
7607fc8990
commit
97353bc64b
@ -13,7 +13,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||
"UPDATE %(table)s SET %(column)s = %(default)s WHERE %(column)s IS NULL"
|
||||
"; 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_create_index = (
|
||||
@ -183,6 +183,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:
|
||||
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
|
||||
``test`` did not work when running parallel tests with the
|
||||
``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`).
|
||||
|
@ -1785,6 +1785,41 @@ class SchemaTests(TransactionTestCase):
|
||||
with connection.schema_editor() as editor:
|
||||
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):
|
||||
"""
|
||||
Should be able to rename an IntegerField(primary_key=True) to
|
||||
|
Loading…
x
Reference in New Issue
Block a user