通过 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
我有一个如下所示的元组列表 -
[(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