summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wobrock <david.wobrock@gmail.com>2022-05-02 14:43:35 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-05-04 12:15:00 +0200
commit8f04473af1da1ed4e8a07e89205da4e70d69b586 (patch)
tree2ecc4b39a4725649b2842a69048170bba87e111f
parentfde946daffbb007a7d033945677cc8e9e475d516 (diff)
Fixed #25105 -- Checked deferred constraints before updating rows on PostgreSQL.
-rw-r--r--django/db/backends/postgresql/schema.py7
-rw-r--r--tests/schema/tests.py32
2 files changed, 39 insertions, 0 deletions
diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py
index 3053c8d370..a22ae0094f 100644
--- a/django/db/backends/postgresql/schema.py
+++ b/django/db/backends/postgresql/schema.py
@@ -7,6 +7,13 @@ from django.db.backends.utils import strip_quotes
class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
+ # Setting all constraints to IMMEDIATE to allow changing data in the same
+ # transaction.
+ sql_update_with_default = (
+ "UPDATE %(table)s SET %(column)s = %(default)s WHERE %(column)s IS NULL"
+ "; SET CONSTRAINTS ALL IMMEDIATE"
+ )
+
sql_delete_sequence = "DROP SEQUENCE IF EXISTS %(sequence)s CASCADE"
sql_create_index = (
diff --git a/tests/schema/tests.py b/tests/schema/tests.py
index 2d12796cbd..fe717f8841 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -973,6 +973,38 @@ class SchemaTests(TransactionTestCase):
Node.objects.update(parent=parent)
editor.alter_field(Node, old_field, new_field, strict=True)
+ @isolate_apps("schema")
+ def test_alter_null_with_default_value_deferred_constraints(self):
+ class Publisher(Model):
+ class Meta:
+ app_label = "schema"
+
+ class Article(Model):
+ publisher = ForeignKey(Publisher, CASCADE)
+ title = CharField(max_length=50, null=True)
+ description = CharField(max_length=100, null=True)
+
+ class Meta:
+ app_label = "schema"
+
+ with connection.schema_editor() as editor:
+ editor.create_model(Publisher)
+ editor.create_model(Article)
+ self.isolated_local_models = [Article, Publisher]
+
+ publisher = Publisher.objects.create()
+ Article.objects.create(publisher=publisher)
+
+ old_title = Article._meta.get_field("title")
+ new_title = CharField(max_length=50, null=False, default="")
+ new_title.set_attributes_from_name("title")
+ old_description = Article._meta.get_field("description")
+ new_description = CharField(max_length=100, null=False, default="")
+ new_description.set_attributes_from_name("description")
+ with connection.schema_editor() as editor:
+ editor.alter_field(Article, old_title, new_title, strict=True)
+ editor.alter_field(Article, old_description, new_description, strict=True)
+
def test_alter_text_field_to_date_field(self):
"""
#25002 - Test conversion of text field to date field.