使用marshmallow_dataclass反序列化JSON字符串时间戳至datetime失败
问题分析与解决
错误原因拆解
dump时的
AttributeError
你的ExampleClass中datetime类型字段实际存储的是字符串而非datetime对象。marshmallow在dump时会调用strftime方法格式化时间,但字符串没有这个方法,因此报错。本质是反序列化阶段未正确将字符串时间戳转为datetime对象。load时的
TypeError
错误地在load方法中传递many参数,正确做法是实例化Schema时传入many=True,而非在load调用中传参。
解决方案与示例代码
步骤1:正确配置字段的时间转换规则
使用typing.Annotated为dataclass的datetime字段绑定marshmallow的DateTime字段,指定时间格式,实现自动的字符串↔datetime转换。
步骤2:正确使用many参数
实例化Schema时传入many=True,用于处理批量数据的反序列化/序列化。
示例代码(ISO格式时间戳)
from dataclasses import dataclass from datetime import datetime from marshmallow_dataclass import class_schema from marshmallow import fields from typing import Annotated @dataclass class ExampleClass: id: int # 绑定DateTime字段,指定ISO格式,自动处理字符串转datetime created_at: Annotated[datetime, fields.DateTime(format='iso')] # 生成Schema类 ExampleSchema = class_schema(ExampleClass) # 测试反序列化(字符串时间戳转ExampleClass实例) json_data = [ {"id": 1, "created_at": "2024-05-20T12:00:00"}, {"id": 2, "created_at": "2024-05-21T13:00:00"} ] # 正确传入many参数:实例化Schema时指定 instances = ExampleSchema(many=True).load(json_data) # 此时instances是ExampleClass实例列表,created_at为datetime对象 # 测试序列化(实例转JSON格式) dump_result = ExampleSchema(many=True).dump(instances) # dump_result中的created_at会被转为ISO格式字符串
适配Unix时间戳字符串的情况
如果你的时间戳是Unix格式(如"1716187200"),可以自定义字段处理:
from marshmallow import fields class UnixTimestampDateTime(fields.DateTime): def _deserialize(self, value, attr, data, **kwargs): # 将字符串格式的Unix时间戳转为整数 if isinstance(value, str): value = int(value) return super()._deserialize(value, attr, data, **kwargs) # 在dataclass中使用自定义字段 @dataclass class ExampleClass: id: int created_at: Annotated[datetime, UnixTimestampDateTime()]
内容的提问来源于stack exchange,提问作者bobglu
相关产品推荐
相关产品推荐

