Хранить бесконечность в Postgres JSON через Django
У меня есть список кортежей, как показано ниже -
[(float.inf, 1.0), (270, 0.9002), (0, 0.0)]
Я ищу простой сериализатор / десериализатор, который поможет мне сохранить этот кортеж в поле jsonb в PostgreSQL.
Я пытался с помощью JSONEncoder().encode(a_math_function)
но не помогло.
Я сталкиваюсь со следующей ошибкой при попытке сохранить приведенный выше список в поле jsonb -
django.db.utils.DataError: invalid input syntax for type json
LINE 1: ...", "a_math_function", "last_updated") VALUES (1, '[[Infinit...
DETAIL: Token "Infinity" is invalid.
Примечание: поле a_math_function имеет тип JSONField()
1 ответ
t=# select 'Infinity'::float;
float8
----------
Infinity
(1 row)
потому что https://www.postgresql.org/docs/current/static/datatype-numeric.html
В дополнение к обычным числовым значениям типы с плавающей точкой имеют несколько специальных значений:
бесконечность
-Infinity
NaN
тем не менее, json не имеет такого возможного значения (если не его строка) https://www.json.org/
value string number object array true false null
таким образом:
t=# select '{"k":Infinity}'::json;
ERROR: invalid input syntax for type json
LINE 1: select '{"k":Infinity}'::json;
^
DETAIL: Token "Infinity" is invalid.
CONTEXT: JSON data, line 1: {"k":Infinity...
Time: 19.059 ms
так что это не ограничение jango или postgres - просто Infinity
пока недействительный токен 'Infinity'
является допустимой строкой. так
t=# select '{"k":"Infinity"}'::json;
json
------------------
{"k":"Infinity"}
(1 row)
работает... но Infinity
здесь "просто слово". Конечно, вы можете сохранить его как строку, а не как числовое значение и проверить каждую строку, если она не равна "Infinity"
и, если это так - запустите логику вашей программы, чтобы рассматривать ее как настоящую бесконечность... Но вкратце - вы не можете этого сделать, потому что спецификация json не поддерживает ее... то же самое, что вы не можете сохранить, скажем, красный #ff0000
как цвет в json - только как строка, чтобы быть пойманным и обработанным вашим движком...
Обновить:
Postgres бросил бы плавающий текст самому себе to_json
:
t=# select to_json(sub) from (select 'Infinity'::float) sub;
to_json
-----------------------
{"float8":"Infinity"}
(1 row)
Обновить
https://www.postgresql.org/docs/current/static/datatype- json.html
При преобразовании текстового ввода JSON в jsonb примитивные типы, описанные в RFC 7159, эффективно отображаются на собственные типы PostgreSQL.
...
число числовые значения NaN и бесконечность не допускаются