Opened 4 years ago
Closed 4 years ago
#32079 closed Bug (invalid)
Using JSONField with Func() crash when returns boolean.
Reported by: | Loic Quertenmont | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hello,
I've jsut migrated to django 3 and I observed a bug when annotating a json field
I have a model with a json field named "references" which is basically a dictionnary,
If I annotate this field using a jsonb_path_exists function through a "Func" as shown bellow
and I then try to fetch or iterate over the results, it crashes in from_db_value (django/db/models/fields/json.py)
because it tries to decode the boolean output of this function via json.loads
qs = qs.annotate(reference_match = Func(F('references'), ('$.* ? (%s)'%condition, ) , function='jsonb_path_exists') print(list(qs)) # fails
changing the line to (adding the output_field of the function) is enough to make it work
qs = qs.annotate(reference_match = Func(F('references'), ('$.* ? (%s)'%condition, ) , function='jsonb_path_exists',, output_field=models.BooleanField()) print(list(qs)) # success
This was not needed in django 2.2.X
Here it seems to believe that the Func has the same time has the referenced field.
Thanks in advance for fixing this.
Loic
PS: I am runnong on postgresql 12
Change History (1)
comment:1 by , 4 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Summary: | 3.1.2 postgresql and JsonField annotation → Using JSONField with Func() crash when returns boolean. |
Thanks for this report. It works in Django < 3.1.1 but not intentionally.
Func()
guesses an output type based onexpressions
types, in this caseJSONField
, PostgreSQL supports primitives injsonb
data type so it treats the result ofjsonb_path_exists()
as aJSONField
. As a consequence of #31956, fetching aJSONField
should return a string instead of pre-loaded data that's why it crashes.I don't think there is anything to fix here, you want to use
jsonb_path_exists()
which takes JSON and returns boolean, so passingoutput_field=models.BooleanField()
should be necessary.