【问题标题】:JSON: TypeError: Decimal('34.3') is not JSON serializable [duplicate]JSON:TypeError:Decimal('34.3')不是JSON可序列化的[重复]
【发布时间】:2015-09-21 01:38:03
【问题描述】:

我正在运行一个返回小数列表的 SQL 查询。当我尝试将其转换为 JSON 时,出现类型错误。

查询:

res = db.execute("""
SELECT CAST ((SUM(r.SalesVolume)/1000.0) AS decimal(6,1))
FROM RawData r
INNER JOIN Product p
ON r.ProductId = p.ProductId 
INNER JOIN Calendar c
ON r.DayId = c.DayId
WHERE c.WeekCodeInYear BETWEEN 1 AND 12
AND 
c.YearId = 2014
GROUP BY c.WeekCodeInYear """)

结果列表:

[Decimal('34.3'), Decimal('50.9'), Decimal('31.5'), Decimal('23.3'), Decimal('19
.7'), Decimal('56.9'), Decimal('43.8'), Decimal('35.2'), Decimal('29.2'), Decima
l('43.7'), Decimal('42.6'), Decimal('23.4')]

代码:

for row in res:
    testlist.append (row[0])
    print testlist

list = json.dumps(testlist)

我得到了Unable to serialize error 上网查了一下,没有太大帮助。 请注意,最终列表将作为图表的输入数据。

【问题讨论】:

  • Decimal object 不是 json 可序列化的。向我们展示print testlist的执行结果
  • @LittleQ 上面的结果列表是testlist的执行
  • 明白你的意思。 BTW,list 是内置类型,最好不要用作变量名

标签: python json


【解决方案1】:

正如错误所说,Decimal 类型无法直接序列化为 JSON。如果您希望将其保留为数字,请考虑将 Decimal 转换为 float,但是您可能会遇到舍入错误。即

for row in res:
    testlist.append(float(row[0]))

或者使用列表理解构建列表,这次我转换为str

testlist = [str(row[0]) for row in res]

后者是一种适当的表示形式,因为Decimal 类型可以明确表示为str。您可以像这样获取原始值

from decimal import Decimal
jlist = json.dumps(testlist)  # don't use list as it's predefined type
new_list = json.loads(jlist)
new_dlist = [Decimal(s) for s in new_list]

new_dlist 应与原始templist 相同。

【讨论】:

  • 如果输入已经在 1 个十进制数字内总是,那么您将始终具有该精度。将其提取出来需要以正确的精度构建Decimal
【解决方案2】:

使用覆盖default

import json
from decimal import Decimal

def default(obj):
    if isinstance(obj, Decimal):
        return str(obj)
    raise TypeError("Object of type '%s' is not JSON serializable" % type(obj).__name__)

json.dumps(testlist, default=default)

或者只是对Decimal 对象执行str

for row in res:
    testlist.append (str(row[0]))
json.dumps(testlist)

【讨论】:

  • 后一种比较简单。
  • 我发现扩展默认类型很棘手,而且我发现有人的库以有组织的方式为更多类型进行了扩展。 pypi.org/project/json-default 另外我想将我的存储为浮点数,所以我将您的第 6 行更改为 float(obj)
  • 就像在顶部的链接示例中SimpleJson 很好地支持Decimalgithub.com/simplejson/simplejson
猜你喜欢
  • 2016-06-22
  • 2018-11-18
  • 2014-04-12
  • 2016-12-20
  • 2019-06-01
  • 1970-01-01
  • 2013-04-26
  • 2018-08-16
相关资源
最近更新 更多