This Django 3.1.3, I only see this with Sqlite, it works fine with MySQL and Postgres.
When I do a path lookup with values like Bob.objects.values("my_json_field__position")
if there is an integer, float or bool in "position" then I get a JSON decode error.
Strings, nones, dicts and lists all work, fetching the top level dict works and filtering on the path lookup works.
TypeError: the JSON object must be str, bytes or bytearray, not float
..\..\.venv\data_browser\lib\site-packages\django\db\models\query.py:287: in __iter__
self._fetch_all()
..\..\.venv\data_browser\lib\site-packages\django\db\models\query.py:1308: in _fetch_all
self._result_cache = list(self._iterable_class(self))
..\..\.venv\data_browser\lib\site-packages\django\db\models\query.py:111: in __iter__
for row in compiler.results_iter(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size):
..\..\.venv\data_browser\lib\site-packages\django\db\models\sql\compiler.py:1100: in apply_converters
value = converter(value, expression, connection)
..\..\.venv\data_browser\lib\site-packages\django\db\models\fields\json.py:79: in from_db_value
return json.loads(value, cls=self.decoder)
This is because SQLite's
JSON_EXTRACT
returns deserialized values. A simple solution is just to addTypeError
here, which will also partially "solve" problems with people who use the JSON data type on PostgreSQL. Another option is to wrap the value inJSON_QUOTE
... which I think might be the better option.I'm guessing there's also a bug in querying
__key
on{"key": "\"value\""}
, which will returnvalue
rather than"value"
. I think wrapping the value inJSON_QUOTE
should fix this as well... but it would break ordering (and maybe some other stuff).