我正在使用 Fastapi、Celery 和 Pydantic(2.4)。我遇到的问题是,当我尝试从字典创建模型实例 (
args = Model(**args)
) 时,setting
值不会转换为 SettingItem
类的实例;相反,它变成了一个字典。
如何使
setting
成为SettingItem的实例?
from typing import List
from pydantic import BaseModel
class SettingItem(BaseModel):
setting_id: str
alias: str
date: str
class Model(BaseModel):
id: str
setting: List[SettingItem]
@app.task
def get_data(args: Model):
if isinstance(args,dict)
args = Model.model_construct(**args)
# this line throws an exception. The root cause is that args.setting is a dict instead of an instance of SettingItem
dates = [x.date for x in args.setting]
...
@api.get("/")
def run(args:Model)
get_data.delay(args.model_dumps())
我已经尝试了
Model.model_validate_json()
和Model.parse_obj()
,但都不起作用
基本上,通过下面的测试,你可以看到
setting
类型是SettingItem
:
d = dict(setting=[dict(setting_id='1', alias='a', date='2023')], id="1")
m = Model(**d)
print(type(m.setting[0]))
出:
__main__.SettingItem
所以与您的
pydantic
模型无关。
问题似乎与此行
get_data.delay(args.model_dumps())
有关,因为您自己将 Model
转换为 dict
。因此,显然,您会在 dict
方法中得到 get_data()
,而不是 Model
。
要解决此问题,您需要在
args
方法中是否直接传递 Model
或将其转换回 get_data()
,如下所示:
@app.task
def get_data(args: dict):
if isinstance(args, dict)
args = Model.model_validate(args)
...
为确保其正常工作,请查看以下内容:
d = dict(setting=[dict(setting_id='1', alias='a', date='2023')], id="1")
m = Model(**d)
dd = m.model_dump() # the thing you have done in run() method
mm = Model.model_validate(dd) # convert it back again from dict to Model
print(type(mm.setting[0]))
出:
__main__.SettingItem
[注意]:
parse_obj()
在 pydantic
版本 2 中已被弃用,因此最好使用 model_validate()
代替。