【问题标题】:Python MongoDB save dictionary of setsPython MongoDB 保存集合字典
【发布时间】:2022-01-22 23:03:08
【问题描述】:

我有一本要永久保存在 mongodb 数据库中的集合字典。但是,我在保存过程中收到错误“无法编码对象:{1, 2},类型:”。我看到一个帖子,其中一个用户的建议是将每个集合保存为一个字典,但这对我来说似乎不是一个好的解决方案。除了将每个集合转换为列表之外,还有其他方法可以将字典与集合一起保存吗?该字典类似于以下代码,但更复杂,并且包含数千个带有字符串键和 set() 值的条目:

{'One': {1, 2}, 'Two': {3, 4}, 'Three': {5, 6}}

【问题讨论】:

  • 您打算以哪种 MongoDB 类型存储集合?
  • 我不知道不同的可能类型,但这实际上并不重要。只要我可以加载数据并再次获取集合字典,哪种类型都没有关系。
  • 当然这很重要。 MongoDB 制定了关于可以在其中保存的内容的规则。并且集合不是这些规则的一部分。
  • 计划在最后再接收集。因此,集合是保存为类型 x 还是类型 y 并不重要,如果我可以轻松地将其再次转换为集合。因此,只要我可以轻松地重建保存的集合字典,我就可以接受任何类型。
  • JSON 和 BSON 不支持集合,因此将它们保存为数组的唯一方法。如果您的驱动程序抱怨意味着它在编码为 BSON 时不会自动将集合转换为数组。解决方案是更改驱动程序代码(编码为 BSON 部分)或在将它们插入数据库之前对其进行转换。

标签: python mongodb dictionary set pymongo


【解决方案1】:

MongoDB 曾经有 SONManipulators 来转换进出数据库的文档,但它们在 4.0 中已被弃用......因此您必须将 sets 预处理为对象,以便在加载时保存和恢复它们。

例子:

test = {'One': {1, 2}, 'Two': {3, 4}, 'Three': {5, 6}}

def unsetify(doc):
    for k, v in doc.items():
        if isinstance(v, dict):
            doc[k] = unsetify(v)
        elif isinstance(v, set):
            doc[k] = { '_type': 'set', '_val': list(v) }
    return doc


def resetify(doc):
    for k, v in doc.items():
        if isinstance(v, dict):
            if v.get('_type', '') == 'set':
                doc[k] = set(v['_val'])
            else:
                doc[k] = resetify(v)
    return doc

doc = unsetify(test)
print(doc)
print(resetify(doc))

输出:

{'One': {'_type': 'set', '_val': [1, 2]}, 'Two': {'_type': 'set', '_val': [3, 4]}, 'Three': {'_type': 'set', '_val': [5, 6]}}
{'One': {1, 2}, 'Two': {3, 4}, 'Three': {5, 6}}

是的,它是递归的,是的,它会在原地破坏输入文档,而不是制作副本等。对于确切的用例可能并不理想(没有更多信息不能说),但演示了原理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 2012-04-27
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多