后端-数据库-新闻删除后收藏未级联清理
问题现象
- 收藏列表第2页点击"加入卡片"提示"操作失败"(第1页正常)
- 服务器日志显示
GET /api/news/web/2334/card 404 Not Found(news_id 不存在) - 影响范围:19 条收藏(18 web + 1 wechat)的引用新闻已被删除
核心问题
-
数据孤岛:
web_news表 ID 2300-2700 范围的全部记录被删除(推测原因:站点删除重建或cleanup_duplicate_news.py --fix去重),但favorites表保留了这些已删除新闻的引用,形成孤儿记录 -
缺少级联清理:
SiteService.delete()只删除 site 记录,不清理关联的web_news和favorites-
cleanup_duplicate_news.py --fix删除重复 news 时,不清理对应的 favorites -
错误信息被吞没:axios 404 拦截器将原始 AxiosError 替换为
new Error('接口不存在(404)'),丢失response.data.detail;前端handleJoinCard未捕获e.message,只显示"操作失败"
查询孤儿收藏的 SQL:
SELECT f.id, f.news_id, f.news_type, f.title
FROM favorites f
LEFT JOIN web_news w ON f.news_id = w.id AND f.news_type = 'web'
LEFT JOIN wechat_articles a ON f.news_id = a.id AND f.news_type = 'public_account'
WHERE (f.news_type = 'web' AND w.id IS NULL)
OR (f.news_type = 'public_account' AND a.id IS NULL);
解决方法
1. 清理孤儿数据(生产服务器)
ssh news
cd /www/news
source venv/bin/activate
python3 -c "
from sqlalchemy import create_engine, text
from dotenv import load_dotenv; import os
load_dotenv()
# ... 执行上面 SQL 的 DELETE 版本
"
2. 修复级联删除(代码层)
modules/web-crawler/service.py:SiteService.delete()删除 site 前先查WebNews.site_id,然后删除对应 favorites 和 newssrc/cli/cleanup_duplicate_news.py:删除重复 web_news 和 wechat_articles 前先清理 favorites
3. 收藏列表自动过滤孤儿
src/service/favorite_service.py:get_list()使用 EXISTS 子查询,只返回 news 真实存在的收藏
4. 前端错误提示优化
web/src/api/request.ts:404 拦截器保留response.data.detail到Error.messageweb/src/views/Favorites.vue:handleJoinCard和removeFavorite显示e.message
下次防错措施
- 快速定位:看到"操作失败"且日志有 404 on
/api/news/*/card,立即查上面孤儿 SQL - 部署后巡检:每次站点删除或 dedup 脚本执行后,运行孤儿查询确认
count = 0 - 流程改进:站点管理中删除站点时弹窗提示"将同时删除 N 条新闻和 M 条收藏"