fix(database): 修复缓存失效逻辑和属性名错误

主要修复:

1. Expression 缓存键生成问题
   - 问题: get_expression_by_chat_id 作为实例方法使用 @cached 时,self 会污染缓存键
   - 解决: 重构为静态方法 _get_expressions_by_chat_id_cached,实例方法调用它
   - 确保缓存键只包含 chat_id,与缓存失效键匹配

2. PersonInfo 删除时的缓存失效
   - 问题: person_id 是哈希值,无法反向得到 platform 和 user_id
   - 解决: 移除不准确的缓存清除代码,依赖 TTL 自动过期
   - 原因: 删除操作很罕见,缓存在 5-10 分钟内会自动过期

3. ChatStreams 属性名错误 (严重 bug)
   - 问题: UserInfo.nickname 应为 UserInfo.user_nickname
   - 问题: UserInfo.cardname 应为 UserInfo.user_cardname
   - 错误导致: AttributeError: 'UserInfo' object has no attribute 'nickname'
   - 修复: 使用正确的属性名

验证:
- 创建了 test_cache_invalidation.py 验证缓存键一致性
- 所有 11 个测试通过
- 验证了缓存失效键与装饰器生成的键匹配
This commit is contained in:
Windpicker-owo
2025-11-01 16:09:28 +08:00
parent 8829a1d124
commit bbe5708cf3
3 changed files with 14 additions and 13 deletions

View File

@@ -232,7 +232,6 @@ class ExpressionLearner:
logger.error(f"为聊天流 {self.chat_name} 触发学习失败: {e}")
return False
@cached(ttl=600, key_prefix="chat_expressions")
async def get_expression_by_chat_id(self) -> tuple[list[dict[str, float]], list[dict[str, float]]]:
"""
获取指定chat_id的style和grammar表达方式带10分钟缓存
@@ -240,12 +239,19 @@ class ExpressionLearner:
优化: 使用CRUD和缓存减少数据库访问
"""
# 使用静态方法以正确处理缓存键
return await self._get_expressions_by_chat_id_cached(self.chat_id)
@staticmethod
@cached(ttl=600, key_prefix="chat_expressions")
async def _get_expressions_by_chat_id_cached(chat_id: str) -> tuple[list[dict[str, float]], list[dict[str, float]]]:
"""内部方法:从数据库获取表达方式(带缓存)"""
learnt_style_expressions = []
learnt_grammar_expressions = []
# 使用CRUD查询
crud = CRUDBase(Expression)
all_expressions = await crud.get_all_by(chat_id=self.chat_id)
all_expressions = await crud.get_all_by(chat_id=chat_id)
for expr in all_expressions:
# 确保create_date存在如果不存在则使用last_active_time
@@ -256,7 +262,7 @@ class ExpressionLearner:
"style": expr.style,
"count": expr.count,
"last_active_time": expr.last_active_time,
"source_id": self.chat_id,
"source_id": chat_id,
"type": expr.type,
"create_date": create_date,
}