You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI调用GET接口时如何将MySQL存储的逗号分隔字符串转为列表?

解决FastAPI中数据库逗号分隔字符串转列表的问题

你的代码存在两个核心问题:

  1. @property 与类中定义的 product_image 字段同名,导致无限递归调用(self.product_image 会反复触发属性 getter),同时FastAPI在ORM模式下会直接读取ORM模型的原始字段值,不会触发这个属性方法。
  2. 字段类型声明为 str,FastAPI序列化时会强制按字符串输出,忽略你的属性转换逻辑。

下面是两种可行的解决方案:

方案一:使用字段验证器(推荐)

通过Pydantic的字段验证器,在数据进入模型时自动将字符串分割为列表,同时修正字段类型声明:

Pydantic v2 版本代码

from pydantic import BaseModel, field_validator

class Shop_page(BaseModel):
    product_title: str
    product_image: list[str]  # 直接声明为列表类型
    class Config:
        orm_mode = True

    @field_validator('product_image', mode='before')
    def split_image_string(cls, value):
        # 若传入的是字符串则分割为列表,兼容已为列表的场景
        if isinstance(value, str):
            return value.split(',')
        return value

Pydantic v1 版本代码

from pydantic import BaseModel, validator

class Shop_page(BaseModel):
    product_title: str
    product_image: list[str]
    class Config:
        orm_mode = True

    @validator('product_image', pre=True)
    def split_image_string(cls, value):
        if isinstance(value, str):
            return value.split(',')
        return value

方案二:使用计算字段(Pydantic v2+)

通过计算字段重新定义 product_image,将原始字符串字段隐藏为私有属性:

from pydantic import BaseModel, computed_field, Field

class Shop_page(BaseModel):
    product_title: str
    # 用私有字段对应数据库的原始字符串字段,通过别名映射
    _product_image: str = Field(alias='product_image')
    
    class Config:
        orm_mode = True
        populate_by_name = True  # 允许通过别名填充数据

    @computed_field(return_type=list[str], alias='product_image')
    def formatted_product_image(self) -> list[str]:
        return self._product_image.split(',')

验证效果

修改模型后,你的GET接口无需改动,返回结果会自动符合预期:

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

内容的提问来源于stack exchange,提问作者boyenec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:56:13