beanie icon indicating copy to clipboard operation
beanie copied to clipboard

[BUG] find(..., fetch_links=True) does not work on Documents with `is_root=True`

Open mozTheFuzz opened this issue 2 years ago • 2 comments

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?

mozTheFuzz avatar Feb 02 '23 07:02 mozTheFuzz

Hi, thank you for the issue. I'll reproduce and fix this if this is a bug.

roman-right avatar Feb 08 '23 11:02 roman-right

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.

roman-right avatar May 24 '23 10:05 roman-right