Opened 3 months ago
Closed 3 months ago
#36440 closed Bug (duplicate)
bulk_update() on JSONField saves JSON null instead of SQL NULL
Reported by: | Adam Johnson | Owned by: | Adam Johnson |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 5.2 |
Severity: | Release blocker | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I have a client project with a Django model that has a JSONField
and a check constraint requiring the field to either contain SQL NULL
or a JSON object (via a custom database function calling PostgreSQL's jsonb_typeof
). Upgrading to Django 5.2 causes a bulk_update()
query on that model to start failing with IntegrityError
, because the JSON null
is serialized instead ('null'::json
in PostgreSQL syntax).
Like #36404 and #36405, this is another bug that bisects to e306687a3a5507d59365ba9bf545010e5fd4b2a8.
The issue:
BaseExpression.resolve_expression()
no longer passes thefor_save
parameter through to source expressions.- When a source expression is a
Value
,for_save
beingFalse
prevents it from callingField.get_db_prep_save()
: https://github.com/django/django/blob/f0a87895ffaf6532a22143b5e2e304c59b7958ae/django/db/models/expressions.py#L1170-L1173 . JSONField.get_db_prep_save()
has specific behaviour forNone
, ensuring it's returned as-is rather than wrapped as JSON: https://github.com/django/django/blob/main/django/db/models/fields/json.py#L110-L111- The missed call means
None
is wrapped as JSON null, which fails the model's check constraint.
Patch incoming.
Change History (2)
comment:1 by , 3 months ago
Summary: | JSON null saved instead of NULL → bulk_update() on JSONField saves JSON null instead of SQL NULL |
---|
comment:2 by , 3 months ago
Resolution: | → duplicate |
---|---|
Status: | assigned → closed |
Duplicate of #36419