返回 pydantic BaseModel 子类列表的 Celery 任务:不是 json 可序列化

Celery task returning a list of pydantic BaseModel subclass: not json serializable

考虑这段代码:

from pydantic import BaseModel

class MyModel(BaseModel):
  x: int

appc = Celery(...)

@appc.task(bind=True)
def mytask(self):
    return [MyModel(x=0)]

res = mytask.delay().get()  # ERROR

错误是:kombu.exceptions.EncodeError: TypeError('Object of type MyModel is not JSON serializable')

我尝试使用 kombu 序列化程序或 pydantic 编码器,但我真的不明白哪里出了问题。

我使用 pickle 序列化以一种简单的方式解决了它:

appc = Celery(
    name=__name__,
    # ...
)


class CeleryConfig:
    task_serializer = "pickle"
    result_serializer = "pickle"
    event_serializer = "json"
    accept_content = ["application/json", "application/x-python-serialize"]
    result_accept_content = ["application/json", "application/x-python-serialize"]


appc.config_from_object(CeleryConfig)

通过这种方式,任务和结果使用 pickle 进行序列化,并且如此处所示 (https://pydantic-docs.helpmanual.io/usage/exporting_models/#pickledumpsmodel),Pydantic 模型可以毫无问题地使用 pickle 转储和加载。

这样:

res = mytask.delay().get()

不仅有效,而且 res 它确实是真实的 List[model] 所以即 res[0].x == 0 是有效和真实的。