我正在使用python编写带有时间戳的OrderedDict,我遇到了问题。我尝试编码的数据如下所示:
SELECT sum(c.amount) - s.total
FROM contribution c inner join (SELECT user_id, sum(solicitude.amount) total
FROM solicitude GROUP BY c.user_id HAVING user_id = 1 AND status_id = 1 )s
on c.user_id=s.user_id GROUP BY c.user_id,s.total HAVING c.user_id = 1
我希望这是json编码和解码,以获得完全相同的数据。
为了直接编码时间戳,不改变ISO或Unix时间,我使用了bson的json_util接口,如下所示。它工作正常。
OrderedDict([('a', datetime.datetime(2015, 6, 15, 15, 58, 54, 884000)), ('b', 'b'), ('c', 'c'), ('d', 'd')])
为了获得OrderedDict,我使用了object_pairs_hook,它也有效:
json.dumps(str, default=json_util.default)
json.loads(jsonstr, object_hook=json_util.object_hook)
然而,当一起使用时,两件事情互相混淆,结果的格式不正确(因为bson界面正在为时间戳创建一个额外的字典)。
json.loads(x, object_pairs_hook=OrderedDict)
此查询最终得到:
json.loads(jsonstr, object_hook=json_util.object_hook, object_pairs_hook=OrderedDict)
未正确解析时间戳。有关如何正确做到这一点的任何建议? (Pickle可能是一个方向,但我首先寻求其他解决方案。)
答案 0 :(得分:2)
您可以定义自己的解码器,它将处理datetime和OrderedDict,并在object_pairs_hook
中使用它。为了方便和测试,我还定义了自己的编码器,但您可以自由使用已经编码的编码器。
#!/usr/bin/env python3
import json
import datetime
from collections import OrderedDict
# Test dictionary
a = OrderedDict([('a', datetime.datetime(2015, 6, 15, 15, 58, 54, 884000)),
('b', 'b'), ('c', 'c'), ('d', 'd')])
print(a)
# Encoder for datetime
def encoder(obj):
if type(obj) is datetime.datetime:
return {'$date$': obj.timestamp()}
raise TypeError
# Encode
s = json.dumps(a, default=encoder)
print("JSON:", s)
# Decoder for OrderedDict and datetime
def decoder(obj):
if len(obj) == 1 and len(obj[0]) == 2 and obj[0][0] == '$date$':
return datetime.datetime.fromtimestamp(obj[0][1])
else:
return OrderedDict(obj)
# Decode
b = json.loads(s, object_pairs_hook=decoder)
print(b)
# Compare
print("Comparing:", a == b)
这将打印:
OrderedDict([('a', datetime.datetime(2015, 6, 15, 15, 58, 54, 884000)), ('b', 'b'), ('c', 'c'), ('d', 'd')])
JSON: {"a": {"$date$": 1434409134.884}, "b": "b", "c": "c", "d": "d"}
OrderedDict([('a', datetime.datetime(2015, 6, 15, 15, 58, 54, 884000)), ('b', 'b'), ('c', 'c'), ('d', 'd')])
Comparing: True
答案 1 :(得分:1)
为什么不直接编码/解码日期时间对象?
import datetime as dt
import json
from collections import OrderedDict
datetime_encoding = '%Y-%m-%d %H:%M.%S %f'
od = OrderedDict([('a', dt.datetime(2015, 6, 15, 15, 58, 54, 884000).strftime(datetime_encoding)), ('b', 'b'), ('c', 'c'), ('d', 'd')])
x = json.dumps(od)
od_new = json.loads(x)
od_new['a'] = dt.datetime.strptime(od_new['a'], datetime_encoding)
>>> od_new
{u'a': datetime.datetime(2015, 6, 15, 15, 58, 54, 884000),
u'b': u'b',
u'c': u'c',
u'd': u'd'}