Home > Mobile >  Response model as list of strings instead of objects
Response model as list of strings instead of objects

Time:02-02

I am trying to return a list of items in FastAPI via a Pydantic model.

Currently I have the route:

from typing import List

from fastapi import Depends
from sqlalchemy.orm.session import Session

...

@router.get('/search-job-types', response_model=List[JobTypeDisplay])
def job_types(search_word: str, db: Session = Depends(get_db)):
  return db_dims.search_job_types(search_word, db)

#db_dims:
def search_job_types(search_word: str, db: Session):
  s_word = search_word.capitalize()
  s_word2 = "%{}%".format(s_word)
  all = db.query(DbJobType).filter(DbJobType.name.like(s_word2)).all()
  #list_jobs = []
  #for item in all:
    #list_jobs.append(item.name)

  return all

And my schema is as the following:

from pydantic import BaseModel

class JobTypeDisplay(BaseModel):
  name: str
  class Config:
        orm_mode = True

I am getting a list of objects like this:

[
  {
    "name": "Something3"
  },
  {
    "name": "Somethin2"
  },
  {
    "name": "Something1"
  }
]

But would like something like this:

['Something3', 'Somethin2', 'Something1']

What is the best way to achieve this and do I really need a loop for it?

CodePudding user response:

You could change to return_model=list[str] and change your return statement to

return [jt.name for jt in all]

CodePudding user response:

If you are only interested in the values of the name column in your DbJobType table, then you should 1) change your database query to actually only select that column and 2) utilize the Result.scalars method to return just a list of strings.

Here is how that would look:

from sqlalchemy.orm.session import Session
from sqlalchemy.sql.expression import select

# ... import DbJobType


def search_job_types(search_word: str, db: Session) -> list[str]:
    ...
    statement = select(DbJobType.name).filter()  # add your filter options here
    result = db.execute(statement)
    return result.scalars().all()

Technically, you also don't need to specify a response_model for the route. If you omit that argument, it will still work. Since there is no additional parsing to be done, a proper return type annotation of list[str] will be enough to generate the correct OpenAPI schema for that route.

from fastapi import Depends, FastAPI
from sqlalchemy.orm.session import Session

# ... import search_job_types


app = FastAPI()
...

@app.get("/search-job-types")
def job_types(search_word: str, db: Session = Depends(get_db)) -> list[str]:
    return search_job_types(search_word, db)

It seems as though, at least for this route, your JobTypeDisplay model is obsolete.

  • Related