Serialization error with MongoDB query

I have an order app that essentially lets the user pick a previously submitted order (that is stored as a MongoDB collection, with the documents pertaining to the purchase items). I’m using an uplink python file that just contains all of the functions used to deal with the database transaction, and so each function essentially returns what the database query received.

I’m able to pull the list of collections to populate a dropdown menu for the user to select from, however after the user selects the collection my uplink/server side code is supposed to retrieve that entire collection that the user selected and display it as a datagrid. Instead when I try to get the collection as a pandas dataframe I’m met with:

anvil.server.SerializationError: Cannot serialize return value from function. Cannot serialize <class 'pandas.core.frame.DataFrame'> object at msg['response']

The two functions that interact with each other are as follows:

# On the client side
# the "order" argument is the selected_value of what the user chose, corresponding with the collection name
def foo():    
    grid_items = anvil.server.call('retrieve_collection', order)


# In my uplink.py file
def retrieve_collection(order_name):
    collection = db[order_name].find({}) 
    df = pandas.Dataframe(list(collection))
    return df

So essentially I’m trying to store the dataframe as the variable grid_items, and the dataframe is retrieved by calling an uplink function that uses the MongoDB find({}) method with {} indicating that I want the entire collection (<20 documents), and returning it as a Pandas dataframe back to the client side. However that aforementioned error code is all that I’m getting.

Two problems here - pandas isn’t supported in the client and it’s not possible to send a pandas dataframe via anvil.server.call.

For a list of python objects that can be sent via anvil.server.call check the docs here.

Anvil Docs | Server Code

There are some other posts related to this topic that might help but generally you’ll want to do something like

@anvil.server.callable
def retrieve_collection(order_name):
    collection = db[order_name].find({}) 
    df = pandas.Dataframe(list(collection))
    return df.to_dict(‘records’)
2 Likes

Hey Stu,

So I tried turning it into a dictionary before returning, however I’m still met with the same type of error, however this time it’s:

Cannot serialize return value from function. Cannot serialize <class 'bson.objectid.ObjectId'> object at msg['response'][0]['_id']

I thought it was because of the “_id” field in the mongo query since it’s of type ObjectID(blah), so I tried excluding it via:

collection = db[order_name].find({}, {"_id": False})
df = pd.Dataframe(list(query))
dt = df.to_dict('records')

This works in Visual Studio Code and when I print(dt) it outputs the correct dictionary without the “_id” field. However, when trying to do this within Anvil I’m met with the aforementioned error from above. I’m a bit confused because the {"_id": False} line should have excluded the “_id” field, however the error still lists Cannot serialize <class 'bson.objectid.ObjectId'> object at msg['response'][0]['_id'].

I’m not sure how else to debug this error since it’s only saying that this error happens at the line where the server function is called. The resources I found online all pertained to excluding the "_id" field which I was able to replicate locally, but it’s not working within the app.