TypeError: Object of type ‘datetime‘ is not JSON serializable

ponponon發表於2021-12-31

pydantic 反序列化的坑:TypeError: Object of type ‘datetime‘ is not JSON serializable

問題描述

有如下需求:

import requests

requests.post('http://localhost/upload/', json=data)

data 應該是一個 dict 型別

data 的 value 不應該有 detetime 型別,如果有 datetime 應該轉為 str

from datetime import datetime, timezone
from datetime import datetime
from pydantic import BaseModel, Field
import requests
import json


def get_utc_now_timestamp() -> datetime:
    return datetime.utcnow().replace(tzinfo=timezone.utc)


class Struct(BaseModel):
    author: str = Field(...)
    releaseDate: datetime = Field(...)


data = Struct(
    author='jike',
    releaseDate=get_utc_now_timestamp()
)


requests.post('http://localhost/upload/', json=data.dict())

上面的程式碼會報錯:TypeError: Object of type ‘datetime‘ is not JSON serializable

為什麼呢?因為 data 應該是一個 dict ,其中的 releaseDate 的 value 應該轉為 str ,而不能是 datetime

而 pydantic 的 dict() 只會把 releaseDate 的 value 轉為 datetime 而不是 str

所以,我們需要修改程式碼:

from datetime import datetime, timezone
from datetime import datetime
from pydantic import BaseModel, Field
import requests
import json


def get_utc_now_timestamp() -> datetime:
    return datetime.utcnow().replace(tzinfo=timezone.utc)


class Struct(BaseModel):
    author: str = Field(...)
    releaseDate: datetime = Field(...)


data = Struct(
    author='jike',
    releaseDate=get_utc_now_timestamp()
).json(ensure_ascii=False)


requests.post('http://localhost/upload/', json=json.loads(data))

pydantic 模型的 json 會把 datetime 型別的欄位轉為 str

解決方案就是:

  • 先呼叫 pydantic 的 json 方法把物件序列化為字串。 ( pydantic object -> str )
  • 在呼叫 json 庫的 loads 方法把字串反序列化為 dict 字典。( str-> dict )

很繞是吧!沒辦法呢!

相關文章