umongo,pymongo,python 3,我如何从参考字段中加载数据

问题描述 投票:0回答:1

我试图了解如何以及为什么难以在unmongo / pymongo中加载引用的数据

@instance.register
class MyEntity(Document):
    account = fields.ReferenceField('Account', required=True)
    date = fields.DateTimeField(
        default=lambda: datetime.utcnow(),
        allow_none=False
    )
    positions = fields.ListField(fields.ReferenceField('Position'))
    targets = fields.ListField(fields.ReferenceField('Target'))

    class Meta:
        collection = db.myentity

当我使用以下方法检索此内容时:

    def find_all(self):
        items = self._repo.find_all(
            {
                'user_id': self._user_id
            }
        )
        return items

然后像这样转储它:

    from bson.json_util import dumps

    all_items = []
    for item in all_items:
        all_items.append(item.dump())


    return dumps(all_items)

我得到以下JSON对象:

[
  {
    "account": "5e990db75f22b6b45d3ce814",
    "positions": [
      "5e9a594373e07613b358bdbb",
      "5e9a594373e07613b358bdbe",
      "5e9a594373e07613b358bdc1"
    ],
    "date": "2020-04-18T01:34:59.919000+00:00",
    "id": "5e9a594373e07613b358bdcb",
    "targets": [
      "5e9a594373e07613b358bdc4",
      "5e9a594373e07613b358bdc7",
      "5e9a594373e07613b358bdca"
    ]
  }
]

并且没有dump

<object Document models.myentity.schema.MyEntity({
'targets':
    <object umongo.data_objects.List([
        <object umongo.frameworks.pymongo.PyMongoReference(
            document=Target,
            pk=ObjectId('5e9a594373e07613b358bdc4')
            )>,
        <object umongo.frameworks.pymongo.PyMongoReference(
            document=Target,
            pk=ObjectId('5e9a594373e07613b358bdc7')
            )>,
        <object umongo.frameworks.pymongo.PyMongoReference(
            document=Target,
            pk=ObjectId('5e9a594373e07613b358bdca'))>]
            )>,
            'id': ObjectId('5e9a594373e07613b358bdcb'),
'positions':
    <object umongo.data_objects.List([
        <object umongo.frameworks.pymongo.PyMongoReference(
            document=Position,
            pk=ObjectId('5e9a594373e07613b358bdbb')
        )>,
        <object umongo.frameworks.pymongo.PyMongoReference(
            document=Position,
            pk=ObjectId('5e9a594373e07613b358bdbe'))>,
        <object umongo.frameworks.pymongo.PyMongoReference(
            document=Position,
            pk=ObjectId('5e9a594373e07613b358bdc1'))>])>,
'date': datetime.datetime(2020, 4, 18, 1, 34, 59, 919000),
'account': <object umongo.frameworks.pymongo.PyMongoReference(document=Account, pk=ObjectId('5e990db75f22b6b45d3ce814'))>
})>
  1. 我真的很在努力如何取消对此的引用。我想递归地将所有加载的字段(如果我在umongo模式中指定它们)取消引用。这不是umongo API中的功能吗?

即如果“目标”中也有参考字段怎么办?我知道这在数据库上可能会很昂贵,但是有什么方法可以在模式定义本身上指定它吗?即在元类中,我总是想要特定字段的完整的,已解引用的对象吗?

  1. 事实上,我发现的文档/评论很少,甚至在umongo文档中也没有提及,而我发现的其他ODM解决方案(如mongoengine)却很费劲地编写了每个字段/每个查询。这向我表明,这不是一个受欢迎的问题是有原因的。可能是反模式吗?如果是这样,为什么?

我不是mongo的新手,而是python / mongo的新手。我觉得这里缺少基本的东西。


编辑:刚发布后,我确实发现了这个问题:

https://github.com/Scille/umongo/issues/42

提供前进的方向

这仍然是最好的方法吗?仍在尝试了解为什么将此视为极端情况。


编辑2:进度

class MyEntity(Document):
    account = fields.ReferenceField('Account', required=True, dump=lambda: 'fetch_account')
    date = fields.DateTimeField(
        default=lambda: datetime.utcnow(),
        allow_none=False
    )
    #trade = fields.DictField()
    positions = fields.ListField(fields.ReferenceField('Position'))
    targets = fields.ListField(fields.ReferenceField('Target'))

    class Meta:
        collection = db.trade

    @property
    def fetch_account(self):
        return self.account.fetch()

因此,使用新定义的属性装饰器,我可以做到:

    items = MyEntityService().find_all()
    allItems = []
    for item in allItems:
        account = item.fetch_account
        log(account.dump())
        allItems.append(item.dump())

当我转帐时,一切都很好。但我不想明确/手动执行此操作。这仍然意味着,每次查询时,我都必须递归解压缩然后重新打包每个引用的文档以及任何子引用。这也意味着模式SOT不再仅包含在umongo类中,即,如果字段发生更改,我将不得不重构使用该字段的每个查询。

我仍在寻找一种在模式本身上修饰/标记它的方法。例如

    account = fields.ReferenceField('Account', required=True, dump=lambda: 'fetch_account')

dump=lambda: 'fetch_account'我刚刚化妆,它什么也没做,但这或多或少是我要使用的模式,不确定这是否可行(甚至很聪明:其他方向,指向我为什么会这么做的指针)欢迎在我的方法中完全错误)....

python-3.x mongodb pymongo odm umongo
1个回答
0
投票

似乎这是umongo中的设计选择。

© www.soinside.com 2019 - 2024. All rights reserved.