Fixed #30266 -- Kept a sequence owner when altering an AutoField/BigAutoField on PostgreSQL.

This commit is contained in:
Dolan Antenucci 2019-03-19 13:28:47 -06:00 committed by Mariusz Felisiak
parent afc708cf6d
commit f944cb3d3b
No known key found for this signature in database
GPG Key ID: 2EF56372BA48CD1B
3 changed files with 33 additions and 0 deletions

View File

@ -243,6 +243,7 @@ answer newbie questions, and generally made Django that much better:
Dmitri Fedortchenko <zeraien@gmail.com> Dmitri Fedortchenko <zeraien@gmail.com>
Dmitry Jemerov <intelliyole@gmail.com> Dmitry Jemerov <intelliyole@gmail.com>
dne@mayonnaise.net dne@mayonnaise.net
Dolan Antenucci <antenucci.d@gmail.com>
Donald Harvey <donald@donaldharvey.co.uk> Donald Harvey <donald@donaldharvey.co.uk>
Donald Stufft <donald@stufft.io> Donald Stufft <donald@stufft.io>
Don Spaulding <donspauldingii@gmail.com> Don Spaulding <donspauldingii@gmail.com>

View File

@ -11,6 +11,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
sql_create_sequence = "CREATE SEQUENCE %(sequence)s" sql_create_sequence = "CREATE SEQUENCE %(sequence)s"
sql_delete_sequence = "DROP SEQUENCE IF EXISTS %(sequence)s CASCADE" sql_delete_sequence = "DROP SEQUENCE IF EXISTS %(sequence)s CASCADE"
sql_set_sequence_max = "SELECT setval('%(sequence)s', MAX(%(column)s)) FROM %(table)s" sql_set_sequence_max = "SELECT setval('%(sequence)s', MAX(%(column)s)) FROM %(table)s"
sql_set_sequence_owner = 'ALTER SEQUENCE %(sequence)s OWNED BY %(table)s.%(column)s'
sql_create_index = "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s)%(extra)s%(condition)s" sql_create_index = "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s)%(extra)s%(condition)s"
sql_delete_index = "DROP INDEX IF EXISTS %(name)s" sql_delete_index = "DROP INDEX IF EXISTS %(name)s"
@ -101,6 +102,14 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
}, },
[], [],
), ),
(
self.sql_set_sequence_owner % {
'table': self.quote_name(table),
'column': self.quote_name(column),
'sequence': self.quote_name(sequence_name),
},
[],
),
], ],
) )
else: else:

View File

@ -4,6 +4,7 @@ import unittest
from copy import copy from copy import copy
from unittest import mock from unittest import mock
from django.core.management.color import no_style
from django.db import ( from django.db import (
DatabaseError, IntegrityError, OperationalError, connection, DatabaseError, IntegrityError, OperationalError, connection,
) )
@ -1103,6 +1104,28 @@ class SchemaTests(TransactionTestCase):
Author.objects.create(name='Foo') Author.objects.create(name='Foo')
Author.objects.create(name='Bar') Author.objects.create(name='Bar')
def test_alter_autofield_pk_to_bigautofield_pk_sequence_owner(self):
"""
Converting an implicit PK to BigAutoField(primary_key=True) should keep
a sequence owner on PostgreSQL.
"""
with connection.schema_editor() as editor:
editor.create_model(Author)
old_field = Author._meta.get_field('id')
new_field = BigAutoField(primary_key=True)
new_field.set_attributes_from_name('id')
new_field.model = Author
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
Author.objects.create(name='Foo', pk=1)
with connection.cursor() as cursor:
sequence_reset_sqls = connection.ops.sequence_reset_sql(no_style(), [Author])
if sequence_reset_sqls:
cursor.execute(sequence_reset_sqls[0])
# Fail on PostgreSQL if sequence is missing an owner.
self.assertIsNotNone(Author.objects.create(name='Bar'))
def test_alter_int_pk_to_autofield_pk(self): def test_alter_int_pk_to_autofield_pk(self):
""" """
Should be able to rename an IntegerField(primary_key=True) to Should be able to rename an IntegerField(primary_key=True) to