1
@router.get("/products", tags=["Product"], response_model=list[schemas.Product])
def get_all_product(db: Session = Depends(get_db)):
    return get_products(db)

def get_products(db: Session):
    products = db.query(models.Product).all()
    return products

The above works fine, when I go to localhost:5000/products I get a JSON file.

I want to save that JSON file on my computer, but the following code returns an error:

def get_all_product(db: Session = Depends(get_db)):
    with open('save_products.json', 'w', encoding = 'utf-8' ) as fp:
        json.dump(get_products(db), fp)
    return get_products(db)

TypeError: Object of type Product is not JSON serializable.

I understand I have to make my 'Product' class serializable, but it seems FastAPI can already do that by itself (otherwise I wouldn't get a JSON file already through my request).

Chris
  • 18,724
  • 6
  • 46
  • 80
Mecar
  • 21
  • 1
  • 1
    `get_products(db)` probably returns a set of SQLAlchemy objects? (since you didn't include that part of your code, it's hard for anyone else to say which type they are); FastAPI converts this through Pydantic (when `from_orm` is configured on the model). You can do the same conversion with `products = parse_obj_as(List[schemas.Product], get_products(db))` - you can then convert these to a dict an serialize them: `json.dump([product.dict() for product in products])`. Does that work for you? – MatsLindh Oct 26 '22 at 13:03

1 Answers1

0

To convert a list of SQLAlchemy objects to their Pydantic representations (which is what FastAPI does internally when you return them), you can use the utility function parse_obj_as from Pydantic.

products = parse_obj_as(List[schemas.Product], get_products(db))

products will now be a list of Pydantic Product objects instead of SQLAlchemy, and these objects can be converted to a dict through Pydantics regular serialization support:

list_of_product_dicts = [product.dict() for product in products])

You can then serialize this list by using json.dump:

json.dump(list_of_product_dicts)
MatsLindh
  • 49,529
  • 4
  • 53
  • 84
  • 1
    This is a good start, but depending on the data types in `schemas.Product`, its `.dict()` might not be JSON serializable (e.g. if it contains a `datetime` object). In that case, you could use `from fastapi.encoders import jsonable_encoder; list_of_product_dicts = jsonable_encoder(products)`. – M.O. Oct 26 '22 at 15:43