Mongoengine:如何递归取消引用文档并将其转换为dict?

时间:2013-06-11 13:42:35

标签: mongodb python-2.7 mongoengine

我需要将mongoengine文档转换为dict,以便在json中对其进行序列化。我已尝试使用to_mongo()方法但ReferenceFields被忽略。在使用DeReference()(video._data)时,我得到了这个结果:

{'audience': 0,
 'channels': [],
 'created_date': datetime.datetime(2006, 1, 2, 12, 11, 3),
 'id': ObjectId('51af7076a2aa1c2179035e8e'),
 'images': {},
 'kind': u'VOD',
 'modified_date': datetime.datetime(2013, 6, 5, 19, 39, 4, 327000),
 'parts': [[<Media: VOD 0x0>,
   <Media: VOD 0x0>,
   <Media: VOD 0x0>,
   <Media: VOD 0x0>]],
 'provider': <Provider: TEST>,
 'published_date': datetime.datetime(2006, 1, 2, 12, 11, 3),
 'sources': [<Source: TEST>],
 'titles': {u'en-US': u'TEST', u'es-ES': u'PRUEBA', u'pt-BR': u'TESTE'}
}

我想要的是递归地取消引用 MediaProviderSource个对象。由于其类型为ReferenceField,我该如何与其联系?

2 个答案:

答案 0 :(得分:3)

要获取ReferenceField值,您需要在引用字段上调用to_mongo() - 而不是父文档,因为它只返回文档的DBRef或ObjectId。

所以在你的例子中 - 你有3个参考字段:providerpartssources给定一个名为my_doc的文档实例来获取引用文档的字典值做:

provider = my_doc.provider.to_mongo()
parts = [part.to_mongo() for part in my_doc.parts]
sources = [source.to_mongo() for source in my_doc.sources]

**旁注

显示的模式似乎是高度关系的,而ReferenceFields导致应用程序连接(MongoEngine必须在内部查询并为您解除引用)。这不具备高级别的性能,无法获取文档的所有部分 - 您需要为文档本身查询一次,为提供者查询一次,为部件查询一次,为源文件查询一次 - 4查询以检索一个文档。对于没有执行queryset.select_related(2)的较大查询集,这意味着 4x查询集计数。这可能是不可取的。

答案 1 :(得分:0)

现在没有开箱即用的方法从DBRef获取数据。但是to_mongo dict conatins:

  1. 简单的项目,如数字,字符串,日期时间,ID等。
  2. DBRef items
  3. 列出项目
  4. dict items
  5. 因此,您可以按列表和dicts进行迭代,并在获取后检查DBRef类型,并将其替换为to_mongo。但是你必须检查你需要哪些引用,你必须获取多深的子引用,如何正确解析自我和递归引用。

    例如,看看mongo python驱动程序如何将python对象转换为自身格式:bson.json_util._json_convert