Я пытаюсь понять, как и почему так сложно загрузить мои ссылочные данные в unmongo / pymon go
@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'))>
})>
- Я действительно борюсь за то, чтобы разыменовать это. Я хотел бы, чтобы рекурсивно, что все загруженные поля, если я укажу их в схеме umon go, разыменовываются. Разве это не в API Umon go?
т.е. что, если в 'target' также есть поле ссылки? Я понимаю, что это может быть дорого на БД, но есть ли способ указать это в самом определении схемы? то есть в мета-классе, что я всегда хочу полный, разыменованный объект для определенного поля?
тот факт, что я нахожу очень мало документации / комментариев по этому поводу, что это даже не упомянуто в документах umon go, а некоторые решения для других ODM, которые я нашел (например, mongoengine), мучительно пишут рекурсивно , ручные функции на поле / на запрос. Это наводит на мысль, что есть причина, по которой этот вопрос не является популярным. Может быть анти-шаблон? если так, то почему?
Я не новичок в mon go, но новичок в python / mon go. Я чувствую, что мне здесь чего-то не хватает.
РЕДАКТИРОВАТЬ: так сразу после публикации, я нашел эту проблему:
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())
Когда я сбрасываю учетную запись, все хорошо. Но я не хочу явно / вручную делать это. Это по-прежнему означает, что я должен рекурсивно распаковывать, а затем перепаковывать каждую ссылку do c и любые дочерние ссылки каждый раз, когда я делаю запрос. Это также означает, что SOT-схема больше не содержится только в классе umon go, т. Е. Если поле изменяется, мне придется проводить рефакторинг каждого запроса, использующего это поле.
Я все еще ищу способ украсить / пометить это на самой схеме. например,
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"
}
]