You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何必须执行session.commit()才能正确处理DateTime数据?

问题解析:DateTime字段需Commit才能正常序列化的原因

核心原因

commit前后,start_time字段的数据类型不一致:

  • 未commit时:你给start_time赋值的是字符串"2022-08-18T17:18:00.000Z",此时这个值还停留在Python模型对象的属性里,没有经过SQLAlchemy/psycopg2的类型转换,依然是字符串类型。
  • commit后:SQLAlchemy会把这个字符串传递给psycopg2,数据库驱动会自动将符合格式的时间字符串转换为Python的datetime.datetime对象,并存回模型实例的start_time属性中。

而toastedmarshmallow.Jit序列化器在处理DateTime类型字段时,只接受datetime对象,无法直接处理字符串,所以未commit时会抛出格式化错误;而id(整数)、string_data(字符串)的类型和字段定义完全匹配,不需要额外转换,因此序列化正常。

细节补充

  1. SQLAlchemy的类型转换时机:SQLAlchemy不会在你给模型属性赋值时立即做类型转换,而是在flush/commit阶段才会将数据传递给数据库驱动,由驱动完成字符串到datetime对象的转换,之后会把转换后的对象同步回模型实例。
  2. toasted-marshmallow的限制:为了追求性能,toasted-marshmallow的JIT序列化器对类型检查更严格,不会自动尝试将字符串解析为datetime对象,必须传入符合字段类型的原生对象。

解决方案(无需Commit即可正常序列化)

手动将时间字符串转换为datetime对象后再赋值:

from datetime import datetime

# 将ISO格式字符串转为带时区的datetime对象
time_obj = datetime.fromisoformat("2022-08-18T17:18:00.000Z".replace("Z", "+00:00"))
time = TheTime(id=3, start_time=time_obj, string_data="Hello, World!")
session.add(time)

# 无需commit,直接序列化即可正常输出
time_schema = TheTimeSchema()
dump_data = time_schema.dump(time)
print(dump_data)

内容的提问来源于stack exchange,提问作者Eric G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:15:45