使用Pydantic.from_orm()转换ORM关联对象为字符串校验报错如何解决
问题原因
UserModel未继承你定义的Base基类,没有启用ORM模式,也不支持from_orm方法。- Pydantic做ORM字段映射时,不会自动调用对象的
__str__方法做类型转换,你声明了phone字段为str类型,但实际传入的是PhoneOrm实例,因此触发类型校验错误。 - 原有代码中的
PhoneOrm、UserOrm缺少构造方法,直接传参实例化会触发报错。
解决方法
使用Pydantic的校验器预处理phone字段,将PhoneOrm对象转换为你需要的字符串格式,修正后的完整代码如下:
import pydantic import sqlalchemy from typing import Optional from pydantic import validator class Base(pydantic.BaseModel): class Config: orm_mode = True class PhoneOrm: id = sqlalchemy.Column( sqlalchemy.Integer, primary_key=True ) number = sqlalchemy.Column( sqlalchemy.String(length=16) ) def __init__(self, number): self.number = number def __str__(self): return f"+{self.number}" class UserOrm: id = sqlalchemy.Column( sqlalchemy.Integer, primary_key=True ) name = sqlalchemy.Column( sqlalchemy.String(length=128) ) phone_id = sqlalchemy.Column( sqlalchemy.Integer, sqlalchemy.ForeignKey('phone.id', ondelete='cascade') ) phone = sqlalchemy.orm.relationship( "PhoneOrm", uselist=False, ) def __init__(self, name, phone): self.id = 1 self.name = name self.phone = phone class UserModel(Base): id: int name: str phone: Optional[str] @validator('phone', pre=True) def parse_phone(cls, value): if not value: return None # 直接取number属性返回不带前缀的号码,符合你要求的输出格式 return value.number # 如果需要带+前缀可以替换为 return str(value) phone = PhoneOrm('799999999999') user = UserOrm(name='John', phone=phone) print(UserModel.from_orm(user).dict())
运行后输出结果为:
{'id': 1, 'name': 'John', 'phone': '799999999999'}
如果你使用的是Pydantic V2版本,将@validator替换为@field_validator('phone', mode='before')即可。
内容的提问来源于stack exchange,提问作者Actticus
相关产品推荐
相关产品推荐

