Skip to content

bugfix: 修改mysql场景下的时间精度不一致的问题 - #322

Open
raychen911 wants to merge 1 commit into
mainfrom
bugfix/mysql_time
Open

bugfix: 修改mysql场景下的时间精度不一致的问题#322
raychen911 wants to merge 1 commit into
mainfrom
bugfix/mysql_time

Conversation

@raychen911

Copy link
Copy Markdown
Contributor

No description provided.

@helloopenworld

Copy link
Copy Markdown
Contributor

AI Code Review

审查结论

通过

审查范围 f05797d..7ada50f,共 6 个文件 +62/-7,主题为修复 MySQL 场景下时间精度不一致问题。核心实现新增 PreciseNow(FunctionElement + @compiles),在 MySQL 下渲染为 CURRENT_TIMESTAMP(6),其余 dialect 委托 func.now(),与计划意图一致且向后兼容,非 MySQL 行为无回归。PreciseNow 作为 default/onupdate/属性赋值的用法与原 func.now() 同类,MySQL 多列 DATETIME(6) 使用 DEFAULT CURRENT_TIMESTAMP(6)/ON UPDATE CURRENT_TIMESTAMP(6) 在 5.6.5+ 合法。计划符合性:部分符合——sessions 表已修复,但同文件 events.timestampapp_states.update_timeuser_states.update_time 及四处手动 func.now() 赋值仍为秒级精度,精度不一致未彻底消除。测试覆盖了 PreciseNow 的 mysql/pg/sqlite 编译输出与再导出,但未覆盖 DDL 渲染。无 SEVERE 级引入缺陷,门禁通过但建议补齐同类表与 DDL 测试。

发现的问题

中等

trpc_agent_sdk/sessions/_sql_session_service.py:159-161

问题: 本次变更新增 PreciseNow 并仅将其应用于 sessions 表的 create_time/update_time(第 159-160 行)及 _get_session 的手动刷新(第 735 行),但同文件中其余同样使用 PreciseTimestamp(MySQL 下为 DATETIME(6))列的时间戳仍使用 func.now()SessionStorageEvent.timestamp(第 225 行)、StorageAppState.update_time(第 342 行)、StorageUserState.update_time(第 359 行),以及 _update_app_state/_get_app_state/_update_user_state/_get_user_state 中四处 storage_*_state.update_time = func.now()(第 676、694、706、719 行)。在 MySQL 上 func.now() 编译为 now(),只具备秒级精度,写入 DATETIME(6) 列时小数秒被截断为 .000000,与已修复的 sessions 表微秒精度再次形成不一致。

触发条件: 在 MySQL 场景下,对 app_statesuser_states 表执行访问/更新(触发 update_time 刷新),或向 events 表写入事件时,时间由 func.now()/now() 生成。

实际影响: 计划标题“修改 mysql 场景下的时间精度不一致的问题”仅对 sessions 表生效,app_statesuser_statesevents 三张表仍为秒级精度,跨表时间精度不一致持续存在;同一秒内多条事件按 timestamp 排序将出现并列,且与 sessions 表的微秒时间无法对齐比较。

修正方向:events.timestampStorageAppState.update_timeStorageUserState.update_timedefault/onupdate 以及第 676、694、706、719 行的手动 func.now() 赋值统一替换为 PreciseNow(),使全部 PreciseTimestamp 列在 MySQL 下都使用 CURRENT_TIMESTAMP(6),彻底消除精度不一致。

较低

tests/storage/test_sql_common.py:282-298

问题: 新增的 TestPreciseNow 仅断言 PreciseNow().compile(dialect=...) 的独立字符串输出(CURRENT_TIMESTAMP(6)/now()/CURRENT_TIMESTAMP),未验证其在 mapped_column(default=, onupdate=) 中实际渲染出的 DDL,也未验证作为属性赋值时 UPDATE 语句的 SET 片段。

触发条件: SQLAlchemy 升级或 @compiles 实现调整后,独立编译输出可能仍正确,但列默认值/onupdate 的 DDL 渲染路径发生回归时无测试拦截。

实际影响: 本次变更的核心契约——MySQL 下 create_time/update_time 列 DDL 为 DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)——缺少回归保护,精度回归可能在不被察觉时引入。

修正方向:TestPreciseNow 中增加用例,对 StorageSession.__table__ 执行 CreateTable(...).compile(dialect=mysql.dialect()),断言 DDL 包含 DEFAULT CURRENT_TIMESTAMP(6)ON UPDATE CURRENT_TIMESTAMP(6)

Comment on lines +159 to 161
create_time: Mapped[datetime] = mapped_column(PreciseTimestamp, default=PreciseNow())
update_time: Mapped[datetime] = mapped_column(PreciseTimestamp, default=PreciseNow(), onupdate=PreciseNow())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

问题: 本次变更新增 PreciseNow 并仅将其应用于 sessions 表的 create_time/update_time(第 159-160 行)及 _get_session 的手动刷新(第 735 行),但同文件中其余同样使用 PreciseTimestamp(MySQL 下为 DATETIME(6))列的时间戳仍使用 func.now()SessionStorageEvent.timestamp(第 225 行)、StorageAppState.update_time(第 342 行)、StorageUserState.update_time(第 359 行),以及 _update_app_state/_get_app_state/_update_user_state/_get_user_state 中四处 storage_*_state.update_time = func.now()(第 676、694、706、719 行)。在 MySQL 上 func.now() 编译为 now(),只具备秒级精度,写入 DATETIME(6) 列时小数秒被截断为 .000000,与已修复的 sessions 表微秒精度再次形成不一致。

触发条件: 在 MySQL 场景下,对 app_statesuser_states 表执行访问/更新(触发 update_time 刷新),或向 events 表写入事件时,时间由 func.now()/now() 生成。

实际影响: 计划标题“修改 mysql 场景下的时间精度不一致的问题”仅对 sessions 表生效,app_statesuser_statesevents 三张表仍为秒级精度,跨表时间精度不一致持续存在;同一秒内多条事件按 timestamp 排序将出现并列,且与 sessions 表的微秒时间无法对齐比较。

修正方向:events.timestampStorageAppState.update_timeStorageUserState.update_timedefault/onupdate 以及第 676、694、706、719 行的手动 func.now() 赋值统一替换为 PreciseNow(),使全部 PreciseTimestamp 列在 MySQL 下都使用 CURRENT_TIMESTAMP(6),彻底消除精度不一致。

Comment on lines +282 to +298
# ---------------------------------------------------------------------------
# PreciseNow SQL expression
# ---------------------------------------------------------------------------


class TestPreciseNow:

def test_compile_mysql_uses_microsecond_precision(self):
sql = str(PreciseNow().compile(dialect=mysql.dialect()))
assert sql == "CURRENT_TIMESTAMP(6)"

def test_compile_postgresql_preserves_default_now(self):
sql = str(PreciseNow().compile(dialect=postgresql.dialect()))
assert sql == "now()"

def test_compile_sqlite_preserves_default_now(self):
sql = str(PreciseNow().compile(dialect=sqlite.dialect()))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

问题: 新增的 TestPreciseNow 仅断言 PreciseNow().compile(dialect=...) 的独立字符串输出(CURRENT_TIMESTAMP(6)/now()/CURRENT_TIMESTAMP),未验证其在 mapped_column(default=, onupdate=) 中实际渲染出的 DDL,也未验证作为属性赋值时 UPDATE 语句的 SET 片段。

触发条件: SQLAlchemy 升级或 @compiles 实现调整后,独立编译输出可能仍正确,但列默认值/onupdate 的 DDL 渲染路径发生回归时无测试拦截。

实际影响: 本次变更的核心契约——MySQL 下 create_time/update_time 列 DDL 为 DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)——缺少回归保护,精度回归可能在不被察觉时引入。

修正方向:TestPreciseNow 中增加用例,对 StorageSession.__table__ 执行 CreateTable(...).compile(dialect=mysql.dialect()),断言 DDL 包含 DEFAULT CURRENT_TIMESTAMP(6)ON UPDATE CURRENT_TIMESTAMP(6)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants