通过django在postgres json中存储无限

时间:2018-01-20 13:53:11

标签: django python-3.x postgresql-9.3 infinity django-postgresql

我有一个像下面这样的元组列表 -

[(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()

1 个答案:

答案 0 :(得分:4)

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

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

  

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

     

无限

     

-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和无穷大值