#36445: Value(None, output_field=JSONField()) incorrectly saves as SQL NULL in
bulk_update()
-------------------------------------+-------------------------------------
     Reporter:  Clifford Gama        |                    Owner:  (none)
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  dev
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Clifford Gama:

Old description:

> When using `bulk_update()` with a `Value(None, output_field=JSONField())`
> expression, the value is incorrectly saved as a `SQL NULL` rather than a
> `JSON null`. This behavior was temporarily fixed in
> 00c690efbc0b10f67924687f24a7b30397bf47d9 due to incomplete `for_save`
> propagation during expression resolution (bug in #36419), but reappears
> after the proper restoration of `for_save` handling in #36419.
>
> {{{#!diff
> djGHOST@anonymous:~/code/django$ git diff
> diff --git a/tests/queries/test_bulk_update.py
> b/tests/queries/test_bulk_update.py
> index 480fac6784..6c553421cb 100644
> --- a/tests/queries/test_bulk_update.py
> +++ b/tests/queries/test_bulk_update.py
> @@ -3,7 +3,7 @@ from math import ceil
>
>  from django.core.exceptions import FieldDoesNotExist
>  from django.db import connection
> -from django.db.models import F
> +from django.db.models import F, Value, JSONField
>  from django.db.models.functions import Coalesce, Lower
>  from django.db.utils import IntegrityError
>  from django.test import TestCase, override_settings, skipUnlessDBFeature
> @@ -315,6 +315,15 @@ class BulkUpdateTests(TestCase):
>                  sql_null_qs =
> JSONFieldNullable.objects.filter(json_field__isnull=True)
>                  self.assertSequenceEqual(sql_null_qs, [obj])
>
> +    @skipUnlessDBFeature("supports_json_field")
> +    def test_json_field_json_null_value(self):
> +        obj = JSONFieldNullable.objects.create(json_field={})
> +        obj.json_field = Value(None, output_field=JSONField())
> +        JSONFieldNullable.objects.bulk_update([obj],
> fields=["json_field"])
> +        obj.refresh_from_db()
> +        json_null_qs = JSONFieldNullable.objects.filter(json_field=None)
> +        self.assertSequenceEqual(json_null_qs, [obj])
> +
>      def test_nullable_fk_after_related_save(self):
>          parent = RelatedObject.objects.create()
>          child = SingleObject()
> }}}

New description:

 When using `bulk_update()` with a `Value(None, output_field=JSONField())`
 expression, the value is incorrectly saved as a `SQL NULL` rather than a
 `JSON null`. This behavior was temporarily fixed in
 00c690efbc0b10f67924687f24a7b30397bf47d9 due to incomplete `for_save`
 propagation during expression resolution (bug in #36419), but reappears
 after the proper restoration of `for_save` handling in #36419.

 {{{#!diff
 diff --git a/tests/queries/test_bulk_update.py
 b/tests/queries/test_bulk_update.py
 index 480fac6784..6c553421cb 100644
 --- a/tests/queries/test_bulk_update.py
 +++ b/tests/queries/test_bulk_update.py
 @@ -3,7 +3,7 @@ from math import ceil

  from django.core.exceptions import FieldDoesNotExist
  from django.db import connection
 -from django.db.models import F
 +from django.db.models import F, Value, JSONField
  from django.db.models.functions import Coalesce, Lower
  from django.db.utils import IntegrityError
  from django.test import TestCase, override_settings, skipUnlessDBFeature
 @@ -315,6 +315,15 @@ class BulkUpdateTests(TestCase):
                  sql_null_qs =
 JSONFieldNullable.objects.filter(json_field__isnull=True)
                  self.assertSequenceEqual(sql_null_qs, [obj])

 +    @skipUnlessDBFeature("supports_json_field")
 +    def test_json_field_json_null_value(self):
 +        obj = JSONFieldNullable.objects.create(json_field={})
 +        obj.json_field = Value(None, output_field=JSONField())
 +        JSONFieldNullable.objects.bulk_update([obj],
 fields=["json_field"])
 +        obj.refresh_from_db()
 +        json_null_qs = JSONFieldNullable.objects.filter(json_field=None)
 +        self.assertSequenceEqual(json_null_qs, [obj])
 +
      def test_nullable_fk_after_related_save(self):
          parent = RelatedObject.objects.create()
          child = SingleObject()
 }}}

--
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36445#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/0107019745ed91f5-dfec998b-ca08-4bc4-a56f-88be58a811f0-000000%40eu-central-1.amazonses.com.

Reply via email to