1

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"]
      }
    ]
boyenec
  • 1,405
  • 5
  • 29
  • Does this answer your question? [pydantic: Using property.getter decorator for a field with an alias](https://stackoverflow.com/questions/63264888/pydantic-using-property-getter-decorator-for-a-field-with-an-alias) – sudden_appearance Jan 28 '23 at 22:18
  • sudden_appearance no this is't – boyenec Jan 28 '23 at 22:25

2 Answers2

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.

Daniil Fajnberg
  • 12,753
  • 2
  • 10
  • 41
0

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)
sudden_appearance
  • 1,968
  • 1
  • 4
  • 15
  • getting this error `Shop_page.from_orm() missing 1 required positional argument: 'obj' (type=type_error)` – boyenec Jan 28 '23 at 22:37
  • Yeah, that is because the `@classmethod` decorator is missing. Also this solution only addresses the specific `from_orm` situation. A better solution is a custom validator because that will work regardless of how you initialize your model. Unfortunately, the annotations here are also wrong/incomplete. – Daniil Fajnberg Jan 29 '23 at 17:11
  • @DaniilFajnberg thanks for noting of missing `@classmethod`. This solution provides instant mapping to list before creating instance of pydantic object. An option using @validator will still be dealing with string and if there are other validators should be considering type mutations as well – sudden_appearance Jan 30 '23 at 07:54