通过 django 在 postgres json 中存储无穷大

store infinity in postgres json via django

我有一个如下所示的元组列表 -

[(float.inf, 1.0), (270, 0.9002), (0, 0.0)]

我正在寻找一个简单的 serializer/deserializer 来帮助我将这个元组存储在 PostgreSQL 的 jsonb 字段中。

我尝试使用 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()

t=# select 'Infinity'::float;
  float8
----------
 Infinity
(1 row)

因为 https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-FLOAT

In addition to ordinary numeric values, the floating-point types have several special values:

Infinity

-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 这里是 "just a word"。当然,您可以将其保存为字符串,而不是数值,并检查每个字符串是否不等于 "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

When converting textual JSON input into jsonb, the primitive types described by RFC 7159 are effectively mapped onto native PostgreSQL types

...

number numeric NaN and infinity values are disallowed