bugfix: 修改mysql场景下的时间精度不一致的问题 - #322
Conversation
AI Code Review审查结论通过 审查范围 f05797d..7ada50f,共 6 个文件 +62/-7,主题为修复 MySQL 场景下时间精度不一致问题。核心实现新增 发现的问题中等
问题: 本次变更新增 触发条件: 在 MySQL 场景下,对 实际影响: 计划标题“修改 mysql 场景下的时间精度不一致的问题”仅对 修正方向: 将 较低
问题: 新增的 触发条件: SQLAlchemy 升级或 实际影响: 本次变更的核心契约——MySQL 下 修正方向: 在 |
| create_time: Mapped[datetime] = mapped_column(PreciseTimestamp, default=PreciseNow()) | ||
| update_time: Mapped[datetime] = mapped_column(PreciseTimestamp, default=PreciseNow(), onupdate=PreciseNow()) | ||
|
|
There was a problem hiding this comment.
问题: 本次变更新增 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_states、user_states 表执行访问/更新(触发 update_time 刷新),或向 events 表写入事件时,时间由 func.now()/now() 生成。
实际影响: 计划标题“修改 mysql 场景下的时间精度不一致的问题”仅对 sessions 表生效,app_states、user_states、events 三张表仍为秒级精度,跨表时间精度不一致持续存在;同一秒内多条事件按 timestamp 排序将出现并列,且与 sessions 表的微秒时间无法对齐比较。
修正方向: 将 events.timestamp、StorageAppState.update_time、StorageUserState.update_time 的 default/onupdate 以及第 676、694、706、719 行的手动 func.now() 赋值统一替换为 PreciseNow(),使全部 PreciseTimestamp 列在 MySQL 下都使用 CURRENT_TIMESTAMP(6),彻底消除精度不一致。
| # --------------------------------------------------------------------------- | ||
| # 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())) |
There was a problem hiding this comment.
问题: 新增的 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)。
No description provided.