mongoengine
mongoengine copied to clipboard
Document not working well with Fastapi & Pydantic
I am trying to integrate Mongoengine ORM with Fastapi but am experiencing an issue when trying to return routes:
demo model:
class ModelName(Document):
name = StringField(required=True)
title = StringField(required=True)
route integration:
router = APIRouter()
@router.get("")
def some_route():
return ModelName.objects()
what is returned:
{
"_cls": "ModelName"
}
When trying to fix the issue, I realized that pydantic tries serializing the document returned but fails due to the __dict__
method not returning serialized data properly. I also tried working with `.to_mongo()', but pydantic failed to serialize the ObjectID fields.
I read some posts on stack overflow and the suggested solution was to return .to_json()
which can be returned as a JSON string, but due to the number of routes making use of this, it would be a hassle to update every single route to return .to_json
, also the frontend dev would have to then parse all responses from the API back to JSON which is unnecessary
I ended up having to create an abstract document with a fix to the __dict__
method:
class CustomDocument(Document):
meta = {"abstract": True}
@property
def __dict__(self):
data = {} # initialize an empty dictionary to store the converted data
# iterate over key-value pairs in the to_mongo() result
for key, value in self.to_mongo().items():
# check if the value is an ObjectId and convert it to a string if necessary
value = str(value) if isinstance(value, ObjectId) else value
# update the dictionary with the key-value pair
data.update({key: value})
return data
class ModelName(CustomDocument):
name = StringField(required=True)
title = StringField(required=True)
returned:
[
{
"_id": "659be429314d05a57b5e7dad"
"name": "some text",
"title": "some text"
}
]
I'd love to know if there is already a solution for this, or possibly one already being worked on. If there isn't, I'll create a pull request with a possible fix to make things easier.
Thank you.