5

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

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

我正在寻找一个简单的序列化器/反序列化器,它可以帮助我将此元组存储在 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()

4

1 回答 1

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

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

除了普通数值外,浮点类型还有几个特殊值:

无穷

-无穷

然而,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 会将 float 转换为文本本身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 和无穷大值是不允许的

于 2018-01-21T11:07:59.137 回答