json null value in a PostgreSQL jsonb column

1,250 views
Skip to first unread message

barth...@infobart.com

unread,
Jul 12, 2016, 9:56:47 AM7/12/16
to Django users
I believe I found a limitation in the Django jsonb support, but I'm really not sure how the framework could fix it beside adding a limitation section in the documentation.

Basically, it is possible to fetch models with json 'null' values but it is not possible to save them back (Django converts the json 'null' value to sql NULL value).

Assume the following model:

class Container(models.Model):
    data = JSONField(blank=False, null=False) # emphasis on null=False


In PostgreSQL, it is perfectly reasonable to do this:

INSERT INTO container VALUES (1, 'null');


If you fetch the row in Django, you will get this:

container = Container.objects.get(pk=1)

assert container.data is None # passes

container.save() # raises IntegrityError because it tries to save NULL in a NOT NULL column.


This is because Django has no idea whether you want to store None or 'null'::jsonb.


I'm not sure if this limitation was discussed elsewhere. I found a somehow-related ticket here: https://code.djangoproject.com/ticket/25718.


Barthélémy

Макс Вернер

unread,
Feb 4, 2020, 8:05:24 AM2/4/20
to Django users

I created a ticket about the similliar problem, but after answer I don't sure that it's bug. Nevertheless, I think It looks contradictory, because you use python None in case of creating, but {{{ __isnull=True }}} in case of filtering.
In case, that I described bellow, it also looks strange. TestModel.objects.create(json_field=None) creates SQL NULL, but TestModel.objects.create(json_field={'key': None}) creates JSON NULL.
May be this behaviour needs to change? Or is it better to extend the documentation?
Is this API allow to create a field with just JSON NULL value?


class TestJsonbNull(TestCase):
   
def setUp(self):
       
TestModel.objects.create(json_field=None)
       
TestModel.objects.create(json_field={'key': None})

   
# test passed
   
def test_1(self):
       
self.assertTrue(TestModel.objects.filter(json_field=None).exists())
   
   
# test failed
   
def test_2(self):
       
self.assertTrue(TestModel.objects.filter(json_field__key=None).exists())

вторник, 12 июля 2016 г., 18:56:47 UTC+5 пользователь barth...@infobart.com написал:
Reply all
Reply to author
Forward
0 new messages