fix(auth): 登录 500——asyncpg 拒绝 aware datetime 写入 naive TIMESTAMP 列
批次5(64dc85b)datetime 弃用清零把 utcnow() 换成 aware 的 now(timezone.utc),而 users.last_login 列是 TIMESTAMP WITHOUT TIME ZONE(sa.DateTime()),asyncpg 编码时抛 DataError → 未捕获 → Starlette 纯文本 500。症状:密码错误正常 401,密码正确反而 500 (错误密码在 commit 前已 return)。 已在生产库实测确认(事务回滚零写入):aware 写入 REJECTED、 naive ACCEPTED、过去 1 小时 last_login 零记录。 - auth_service: last_login 改存 naive UTC(.replace(tzinfo=None)), JWT exp 不受影响仍用 aware - experience_feedback_service: expires_at 同为 naive 列,提交/查询 两处 aware now 一并修掉(线上尚无此表,属前瞻性修复) Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -223,7 +223,9 @@ class ExperienceFeedbackService:
|
||||
role_code = "user"
|
||||
|
||||
# 6. 写 ExperienceFeedback
|
||||
now = datetime.now(timezone.utc)
|
||||
# expires_at 列是 naive TIMESTAMP(sa.DateTime()),asyncpg 拒绝 aware datetime
|
||||
# (DataError → 提交反馈 500);存库/比较统一 naive UTC(同 auth last_login 修复)
|
||||
now = datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
new_ttl = now + timedelta(days=FEEDBACK_TTL_DAYS)
|
||||
feedback = ExperienceFeedback(
|
||||
processing_task_id=processing_task.id,
|
||||
@@ -274,7 +276,8 @@ class ExperienceFeedbackService:
|
||||
排除 expires_at < now() 的过期反馈;按 material_family + is_foam 锚定;
|
||||
按 scheme_axis 聚合(adopted/rejected/adjust 计数 + 加权 confidence)。
|
||||
"""
|
||||
now = datetime.now(timezone.utc)
|
||||
# 同上:expires_at 是 naive TIMESTAMP,SQL 参数也不能传 aware datetime
|
||||
now = datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
is_foam_str = "true" if is_foam else "false"
|
||||
mat_lower = (material_name or "").lower()
|
||||
if "al" in mat_lower and "si" in mat_lower:
|
||||
|
||||
@@ -142,7 +142,11 @@ async def authenticate_user(db_session: AsyncSession, username: str, password: s
|
||||
if not verify_password(password, user.hashed_password):
|
||||
return None
|
||||
|
||||
user.last_login = datetime.now(timezone.utc)
|
||||
# last_login 列是 TIMESTAMP WITHOUT TIME ZONE(sa.DateTime()),asyncpg 拒绝写入
|
||||
# 带 tzinfo 的 datetime(DataError → 登录 500):批次5 弃用清理把 utcnow() 换成
|
||||
# aware 时间后,任何一次成功登录都会在 commit 处炸掉。存库统一 naive UTC,
|
||||
# JWT exp(上方 create_access_token)不受影响,仍用 aware。
|
||||
user.last_login = datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
await db_session.commit()
|
||||
|
||||
return user
|
||||
|
||||
Reference in New Issue
Block a user