You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

2.7 KiB

时间戳时区问题修复

日期: 2026-01-28
类型: Bug 修复
影响范围: 全局数据库模型

问题描述

用户服务 API 测试时发现时间戳类型不匹配错误:

asyncpg.exceptions.DataError: invalid input for query argument $19: 
datetime.datetime(2026, 1, 28, 9, 47, 15... 
(can't subtract offset-naive and offset-aware datetimes)

根本原因

  1. 数据库表使用 TIMESTAMP WITHOUT TIME ZONE
  2. Python 代码使用 datetime.now(timezone.utc) 生成 timezone-aware datetime
  3. SQLAlchemy 模型未明确指定 timezone=True

解决方案

1. 数据库迁移

创建迁移脚本 20260128_2230_fix_timestamp_timezone.py,将所有表的时间戳字段从 TIMESTAMP 改为 TIMESTAMPTZ

涉及表

  • users, user_sessions, sms_verification_codes
  • folders, folder_members
  • projects, project_members, project_shares, project_versions
  • recharge_orders, payment_callbacks
  • ai_models, ai_jobs, ai_quotas, ai_usage_logs

SQL 示例

ALTER TABLE users 
ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC',
ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'UTC',
ALTER COLUMN deleted_at TYPE TIMESTAMPTZ USING deleted_at AT TIME ZONE 'UTC';

2. 模型定义修复

在 SQLModel 字段定义中明确指定 DateTime(timezone=True)

修改文件

  • server/app/models/user.py
  • server/app/models/sms.py

修改示例

from sqlalchemy import DateTime

created_at: datetime = Field(
    default_factory=lambda: datetime.now(timezone.utc),
    sa_column=Column(DateTime(timezone=True), nullable=False)
)

注意事项

  • 不能同时使用 nullable 参数和 sa_column
  • 所有 datetime 字段都需要明确指定 timezone=True

测试结果

运行 test_user_api.py 测试脚本:

成功率: 87.5% (7/8)

通过的测试

  1. 健康检查
  2. 发送短信验证码
  3. 手机号登录
  4. 获取当前用户信息
  5. 更新用户信息
  6. 查询积分信息
  7. 用户登出

失败的测试

  • 绑定邮箱(业务逻辑正确,邮箱已被绑定)

影响范围

  • 用户服务 API 全部正常
  • 时间戳存储和查询正确
  • 符合 datetime-timezone-standards.md 规范

后续工作

需要修复其他模型的 datetime 字段定义:

  • server/app/models/folder.py
  • server/app/models/project.py
  • server/app/models/ai_*.py
  • server/app/models/credit/*.py
  • server/app/models/recharge/*.py

相关文档

  • docs/architecture/datetime-timezone-standards.md - 时间戳规范
  • server/alembic/versions/20260128_2230_fix_timestamp_timezone.py - 迁移脚本
  • server/test_user_api.py - API 测试脚本