我正在尝试通过pyMongo将YAML(JSON的各个行)插入到mongoDB中。我的一些密钥包含句点,这会产生错误bson.errors.InvalidDocument: key 'job.no' must not contain '.'
。根据{{3}},我需要迭代我的键来替换句号,这是有道理的。
我遇到的问题是我的数据很混乱。我的json包含嵌套对象的层,我不知道包含句点的字符串是什么,或者它在哪里(哪个级别)。这是我的数据的一小部分样本。
{"uuid":"94e31-02f59","project":{"name":"oasis","job.no":215493452,"subset":"beta"},"time":1412371841024}
我有一个递归迭代我的JSON的函数。我尝试了一些变体,但它要么压平我的JSON(没有更多的嵌套对象),要么只返回第一个对象。我想保持输入的结构。
def keyCleaner(line):
for k, v in line.iteritems():
if isinstance(v, dict):
keyCleaner(v)
else:
nK = k
if "." in k:
nK = k.replace(".", "_")
return nK, v
这是它目前的回报:
(u'uuid', u'94e31-02f59')
我希望它返回的是:
{"uuid":"94e31-02f59","project":{"name":"oasis","job_no":215493452,"subset":"beta"},"time":1412371841024}
但我没看到这是如何结合在一起的。有人可以帮忙吗?
答案 0 :(得分:3)
这种递归解决方案怎么样?请注意,由于标准的Python递归限制,深层嵌套的字典可能无法正常工作。
#!/usr/bin/env python
# parse initial string
import json
def keyCleaner(d):
if type(d) is dict:
for key, value in d.iteritems():
d[key] = keyCleaner(value)
if '.' in key:
d[key.replace('.', '_')] = value
del(d[key])
return d
if type(d) is list:
return map(keyCleaner, d)
if type(d) is tuple:
return tuple(map(keyCleaner, d))
return d
print keyCleaner(json.loads('{"uuid":"94e31-02f59","project":{"name":"oasis","job.no":215493452,"subset":"beta"},"time":1412371841024}'))
答案 1 :(得分:0)
一个对我有用的麻烦的解决方案(但是您需要跟踪代码中的修改)是简单地包装包含“。”的字典。在python列表中并将列表存储在mongo中,而不是存储字典(这会引发错误)。
new_item_to_store = list(dict_to_store.items())
我在存储域字典时遇到问题,即:
{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}
上面显示了mongo store key 'job.no' must not contain '.'
中的错误,但这可以正常工作:
[{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}]