我正在试图理解为什么在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'))>
})>,
也就是说,如果在“目标”中也有一个参考字段,那该怎么办?我知道这在DB上是很昂贵的,但是有什么方法可以在模式定义本身上指定这一点吗?也就是说,在元类中,我总是想要一个特定字段的完整的、取消引用的对象?
我对芒果并不陌生,但对巨蟒/蒙戈来说却是新的。我觉得我错过了一些最基本的东西。
编辑:所以在发帖后,我确实找到了这个问题:
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'我刚刚编好了,它什么也不做,但这或多或少是我想要的模式,我不确定这是否可能(甚至是聪明的:其他方向,指点为什么我的方法完全错误是值得欢迎的).
编辑3:这就是我登陆的地方:
@property
def fetch_account(self):
return self.account.fetch().dump()
@property
def fetch_targets(self):
targets_list = []
for target in self.targets:
doc = target.fetch().dump()
targets_list.append(doc)
return targets_list
@property
def fetch_positions(self):
positions_list = []
for position in self.positions:
doc = position.fetch().dump()
positions_list.append(doc)
return positions_list然后进入:
allItems = []
for item in items:
account = item.fetch_account
positions = item.fetch_positions
targets = item.fetch_targets
item = item.dump()
item['account'] = account
item['positions'] = positions
item['targets'] = targets
# del item['targets']
allTrades.append(item)我可以清理它/抽象它一些,但我不知道在这一点上我如何才能真正减少一般的冗长。不过,这似乎确实给了我我想要的结果:
[
{
"date": "2020-04-18T01:34:59.919000+00:00",
"targets": [
{
"con_id": 331641614,
"value": 106,
"date": "2020-04-18T01:34:59.834000+00:00",
"account": "5e990db75f22b6b45d3ce814",
"id": "5e9a594373e07613b358bdc4"
},
{
"con_id": 303019419,
"value": 0,
"date": "2020-04-18T01:34:59.867000+00:00",
"account": "5e990db75f22b6b45d3ce814",
"id": "5e9a594373e07613b358bdc7"
},
{
"con_id": 15547841,
"value": 9,
"date": "2020-04-18T01:34:59.912000+00:00",
"account": "5e990db75f22b6b45d3ce814",
"id": "5e9a594373e07613b358bdca"
}
],
"account": {
"user_name": "hello",
"account_type": "LIVE",
"id": "5e990db75f22b6b45d3ce814",
"user_id": "U3621607"
},
"positions": [
{
"con_id": 331641614,
"value": 104,
"date": "2020-04-18T01:34:59.728000+00:00",
"account": "5e990db75f22b6b45d3ce814",
"id": "5e9a594373e07613b358bdbb"
},
{
"con_id": 303019419,
"value": 0,
"date": "2020-04-18T01:34:59.764000+00:00",
"account": "5e990db75f22b6b45d3ce814",
"id": "5e9a594373e07613b358bdbe"
},
{
"con_id": 15547841,
"value": 8,
"date": "2020-04-18T01:34:59.797000+00:00",
"account": "5e990db75f22b6b45d3ce814",
"id": "5e9a594373e07613b358bdc1"
}
],
"id": "5e9a594373e07613b35
8bdcb"
}
]发布于 2020-04-18 18:42:44
这似乎是乌龙戈的一个设计选择。
例如,在Mongoid ( Ruby for MongoDB)中,当引用对象时,会根据需要通过关联从数据库中自动获取对象。
顺便说一下,在ODM中,“定义字段结构”和“通过应用程序对象无缝访问数据”的功能是完全独立的。例如,我在Java中使用Hibernate的经验表明,它与您在umongo中发现的类似--一旦加载了数据,它就提供了一种使用应用程序定义的具有类型等字段结构访问数据的方法,但它实际上无助于透明地从应用程序域加载数据。
https://stackoverflow.com/questions/61292375
复制相似问题