Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Set Optional params in PUT method using fastAPI/mongodb

I am trying to set Optional some params in a PUT method from my API.
Using fastAPI and mongodb I’ve build a simple API to insert students and delete the ones, now I am looking to allow me update the entries but not mandatory "params".

I’ve checked this Fastapi: put method and looks like something I am looking for mongodb.

And this response from art049 looks similar what I already have in my @api_router.put('/update-student/{id}', tags=['Student']) MongoDb with FastAPI

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

As example for my question here I have this structure:

Models:

class Student(BaseModel):
    age:int
    name:str
    address:str

class UpdateStudent(BaseModel):
    age: Optional[int] = None
    name: Optional[str] = None
    address: Optional[str] = None

Schemas:

def serializeDict(a) -> dict:
    return {**{i:str(a[i]) for i in a if i=='_id'},**{i:a[i] for i in a if i!='_id'}}

def serializeList(entity) -> list:
    return [serializeDict(a) for a in entity]

Routes:

@api_router.post('/create-student', tags=['Students'])
async def create_students(student: Student):
    client.collegedb.students_collection.insert_one(dict(student))
    return serializeList(client.collegedb.students_collection.find())

Also I know I can update the entry without problems in this way:

@api_router.put('/update-student/{id}', tags=['Student'])
async def update_student(id,ustudent: UpdateStudent):
    client.collegedb.students_collection.find_one_and_update({"_id":ObjectId(id)},{
        "$set":dict(ustudent)
    })
    return serializeDict(client.collegedb.students_collection.find_one({"_id":ObjectId(id)}))

My problem as you can see with my Models I need a way to validate which params are modified and update the ones only:
If right now I Update for example the age only; since the other params are not required, name and address will be stored as None (null actually) because I set this in my model.

Maybe I can do something like this:

if ustudent.age != None:
    students_collection[ObjectId(id)] = ustudent.age
if ustudent.name != None:
    students_collection[ObjectId(id)] = ustudent.name
if ustudent.address != None:
    students_collection[ObjectId(id)] = ustudent.address

I know I can use this in a simple dictionary but never tried before in a collection in mongodb since pydantic not support ObjectId for iterations and that’s why serializeDict was created.

I will really appreciate if somebody can give a hint with my concern

>Solution :

You can use exclude_unset=True argument as suggested in FastAPI documentation:

@api_router.put('/update-student/{id}', tags=['Student'])
async def update_student(id,ustudent: UpdateStudent):
    client.collegedb.students_collection.find_one_and_update({"_id":ObjectId(id)},{
        "$set":ustudent.dict(exclude_unset=True)
    })
    return serializeDict(client.collegedb.students_collection.find_one({"_id":ObjectId(id)}))

Here is the documentation for exporting Pydantic models.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading