beanie
beanie copied to clipboard
[BUG] find(..., fetch_links=True) does not work on Documents with `is_root=True`
Describe the bug *beanie=1.17.0
I have three objects, BookingInfoBase, BookingInfoDoc1 and BookingStatusDoc1
BookingInfoDoc1 class inherits from BookingInfoBase and it is also linked to BookingStatusDoc1. See the structure in python in the followings:
class BookingStatusDoc1(Document):
id: str
is_default: int
description: Optional[str] = None
class BookingInfoBase(Document):
"""
# BookingInfoBase
# |
# |
# BookingInfoDoc1
"""
company: str
id: str
class Settings:
is_root = True
name = 'BookingInfoCollection'
class BookingInfoDoc1(BookingInfoBase):
record_date: str
start_date: str
end_date: str
status: Optional[int] = None
status_payload: Optional[Link[BookingStatusDoc1]] = None
I query BookingInfoBase via find
with both fetch_links=True
and with_children=True
.
The find'
method returns BookingInfoDoc1 with BookingStatus as an unfetched link object, namely: <beanie.odm.fields.Link object at xxxxx>
.
To Reproduce
search_result = BookingInfoBase.find(fetch_links=True, with_children=True).to_list()
for booking in search_result:
print(f'booking type: {type(booking)} \n \n data is: {booking})
The returned value are as the followings:
booking type:
<class 'booking.model.mongo_db.booking.BookingInfoDoc1'>
data is:
id='smarteroa-5668'
company='smarteroa'
record_date='2023-01-28 17:42:34'
start_date='2023-02-02 19:00:00'
end_date='2023-02-02 20:30:00'
status=smarteroa-1
status_payload=<beanie.odm.fields.Link object at 0x7fcbe90acd60>
Expected behavior I except the returned value be the following:
booking type:
<class 'booking.model.mongo_db.booking.BookingInfoDoc1'>
data is:
id='smarteroa-5668'
company='smarteroa'
record_date='2023-01-28 17:42:34'
start_date='2023-02-02 19:00:00'
end_date='2023-02-02 20:30:00'
status=smarteroa-1
status_payload=
BookingStatusDoc1(
id='smarteroa-1'
is_default=0
description:"yet to confirm"
)
Additional context
I following the demotration on the Documentation-Inheritance though the demo did not use is_root
and link
to its children.
I manage to figure out a work-around by re-iterate search_result
and use fetch_all_links
to its item but this is cumbersome.
search_result = BookingInfoBase.find(fetch_links=True, with_children=True).to_list()
for booking in search_result:
await booking.fetch_all_links()
print(f'booking type: {type(booking)} \n \n data is: {booking})
I wonder if there is any parameter is missed to have the aforementioned inheritance-link case to work elegantly?
Hi, thank you for the issue. I'll reproduce and fix this if this is a bug.
I have checked this, and at this moment, it is impossible to fix as it is not a mistake. For link prefetching, I use aggregation pipelines. To support this case, I have to run different aggregation pipelines for different child classes and merge the result there in the aggregation to make the whole operation atomic. I don't say that it is impossible, but it requires a lot of experimentation.
I have converted it from a bug to a feature request.