Хранить бесконечность в 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 и бесконечность не допускаются

Другие вопросы по тегам