#36419 closed Bug (fixed)
bulk_update() incorrectly updates JSONField None to JSON 'null' instead of SQL NULL
Reported by: | Clifford Gama | Owned by: | Clifford Gama |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 5.2 |
Severity: | Release blocker | Keywords: | |
Cc: | Simon Charette, Sage Abdullah, Adam Johnson | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Failing test:
-
tests/queries/test_bulk_update.py
diff --git a/tests/queries/test_bulk_update.py b/tests/queries/test_bulk_update.py index 765fa934ca..2d24a74a60 100644
a b class BulkUpdateTests(TestCase): 300 300 JSONFieldNullable.objects.filter(json_field__has_key="c"), objs 301 301 ) 302 302 303 @skipUnlessDBFeature("supports_json_field") 304 def test_json_field_none_value(self): 305 """Top level None value must be equivalent to SQL NULL in db.""" 306 obj = JSONFieldNullable.objects.create(json_field={"k": "v"}) 307 obj.json_field = None 308 JSONFieldNullable.objects.bulk_update([obj], fields=["json_field"]) 309 obj.refresh_from_db() 310 qs = JSONFieldNullable.objects.filter(json_field__isnull=True) 311 self.assertSequenceEqual(qs, [obj]) 312 303 313 def test_nullable_fk_after_related_save(self): 304 314 parent = RelatedObject.objects.create() 305 315 child = SingleObject()
This is inconsistent with create()
, update()
and save()
(see test and docs), and can cause unexpected behaviour when a JSONField has null=False
, since JSON null
does not violate null=False
.
Change History (14)
comment:1 by , 7 weeks ago
Has patch: | set |
---|
comment:2 by , 7 weeks ago
Cc: | added |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 7 weeks ago
Summary: | bulk_update() incorrectly updates top-level JSONField value to JSON 'null' instead of SQL NULL → bulk_update() incorrectly updates JSONField None to JSON 'null' instead of SQL NULL |
---|
Thanks for the triage, Natalia.
comment:4 by , 6 weeks ago
Severity: | Normal → Release blocker |
---|
#36440 was a dupe. Adam bisected it to 5.2 commit e306687a3a5507d59365ba9bf545010e5fd4b2a8, so elevating to blocker for now.
comment:5 by , 6 weeks ago
Cc: | added |
---|
comment:6 by , 6 weeks ago
Version: | dev → 5.2 |
---|
comment:7 by , 6 weeks ago
Severity: | Release blocker → Normal |
---|
For what is worth, the test_json_field_json_null_value
as presented in the proposed branch fails in 5.1.x, 4.2.x, 4.1.x, 4.0.x and 3.2.x, so unclear this is truly a release blocker for 5.2.x.
Adam, could you provide more details about your bisect outcome?
comment:8 by , 6 weeks ago
Severity: | Normal → Release blocker |
---|
Hello Natalia. I did a git bisect for test_json_field_sql_null_value
and the issue is indeed a regression in 00c690efbc0b10f67924687f24a7b30397bf47d9. The test by test_json_field_json_null_value
is something I had assumed to have always worked and isn't actually a regression test for the issue in this ticket.
It seems bulk_update()
was creating SQL NULL
even for Value(None, output_field=JSONField())
maybe since JSONField was introduced.
comment:9 by , 6 weeks ago
Adam, could you provide more details about your bisect outcome?
I bisected for my client project failure, so unfortunately, I can't really share that. I found that the client test failed for e306687a3a5507d59365ba9bf545010e5fd4b2a8.
I then minimized the issue into the test provided in https://github.com/django/django/pull/19527 , which reproduces the exception I encountered. I didn't bisect with that test before.
I just tried bisecting with it and found 1df0f998ae8d1626adaa9b807a43e4cbdfc590e2, the 5.2 backport of 00c690efbc0b10f67924687f24a7b30397bf47d9, is indeed the first commit that makes my test fail.
So it seems we're working on the same issue, but it may be that there may be some other failure lurking in the client project test. I'll try to check, but no promises!
comment:10 by , 6 weeks ago
Triage Stage: | Accepted → Ready for checkin |
---|
Hello Clifford, thank you for your investigation on #36418 and for creating this ticket. If you ask me, I think the reporter in #36418 was reporting this exact same thing, but I also agree the report was a bit confusing (since it was not stated what was the expected outcome). I'll be accepting this ticket based on that, and also because for models with a
null=False
JSONField, this code does raiseIntegrityError
:but
bulk_update
does not.