skip to Main Content

I am using mysql database and it’s doesn’t support list if I stored sting like "apple","banana" in my mysql database then when using get method fastapi how to convert theme from string to list like ["apple","banana"]. I tried this but didn’t work and also not getting the image fields until I remove @property.

class Shop_page(BaseModel):
      product_title: str
      product_image: str
      class Config():
          orm_mode = True
      @property
      def product_image(self):
        return self.product_image.split(",")

here is my get method

@router.get("/shop_page", response_model=List[schemas.Shop_page],status_code=status.HTTP_200_OK)
async def create_variations(db: Session = Depends(get_db)):
          parent_item = db.query(models.ParentProduct).all()
          return parent_item

my result look like now

[
  {
    "product_title": "DEMO PRODUCT",
    "product_image": "image1_url,image2_url"
  }
]

my expected result will be look like this

[
      {
        "product_title": "DEMO PRODUCT",
        "product_image": ["image1_url,image2_url"]
      }
    ]

2

Answers


  1. Pydantic does not support @property decorator serializing

    And I think you can just override from_orm method as follows:

    from typing import Type, Any
    
    from pydantic import BaseModel, validator
    
    
    class ShopPage(BaseModel):
        product_title: str
        product_image: list
    
        class Config:
            orm_mode = True
        
        @classmethod
        def from_orm(cls: Type['Model'], obj: Any):
            if hasattr(obj, "product_image") and isinstance(obj.product_image, str):
                obj.product_image = obj.product_image.split(",")
    
            return super().from_orm(obj)
    
    Login or Signup to reply.
  2. This is what validators are for. But you need to define the schema the way you actually want it, not the way you receive it from your ORM. That means product_image should be annotated as a list[str] and your validator with pre=True will handle the case, if you try and initialize it with a string instead:

    from pydantic import BaseModel, validator
    
    
    class ShopPage(BaseModel):
        product_title: str
        product_image: list[str]
    
        class Config:
            orm_mode = True
    
        @validator("product_image", pre=True)
        def split_urls(cls, v: object) -> object:
            if isinstance(v, str):
                return v.split(",")
            return v
    
    
    if __name__ == "__main__":
        class TestORM:
            product_title = "foo"
            product_image = "bar,baz"
    
        obj = ShopPage.from_orm(TestORM)
        print(obj.json(indent=2))
    

    Output:

    {
      "product_title": "foo",
      "product_image": [
        "bar",
        "baz"
      ]
    }
    

    The advantage of the validator approach is that it will apply regardless of how you initialize ShopPage and can even apply during assignment, if you configure your model with validate_assignment = True. So even if you do ShopPage(product_title="a", product_image="b,c"), you’ll get the product_image as a list.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search