我试图了解如何以及为什么难以在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'))>
})>
即如果“目标”中也有参考字段怎么办?我知道这在数据库上可能会很昂贵,但是有什么方法可以在模式定义本身上指定它吗?即在元类中,我总是想要特定字段的完整的,已解引用的对象吗?
我不是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'
我刚刚化妆,它什么也没做,但这或多或少是我要使用的模式,不确定这是否可行(甚至很聪明:其他方向,指向我为什么会这么做的指针)欢迎在我的方法中完全错误)....
似乎这是umongo中的设计选择。