mysql数据链接更新
This commit is contained in:
Binary file not shown.
@@ -128805,3 +128805,392 @@
|
|||||||
→ module: 'NewsAPIClient'
|
→ module: 'NewsAPIClient'
|
||||||
2025-09-18 15:57:08.084 | INFO | news_api:301 - 本次最新更新时间: 2025-09-18 07:53:49
|
2025-09-18 15:57:08.084 | INFO | news_api:301 - 本次最新更新时间: 2025-09-18 07:53:49
|
||||||
→ module: 'NewsAPIClient'
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:30.261 | INFO | news_api:38 - 新闻API客户端初始化完成,已连接到数据库
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:30.313 | DEBUG | mysql_agent:591 - 查询执行完成
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ 行数: 1
|
||||||
|
2025-09-19 13:57:30.321 | DEBUG | mysql_agent:591 - 查询执行完成
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ 行数: 8
|
||||||
|
2025-09-19 13:57:30.322 | INFO | news_api:76 - 数据库表结构验证通过,当前字段:['id', '文章标题', '文章链接', '文章摘要', '发布时间', '来源URL', '创建时间', '更新时间']
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:30.323 | DEBUG | news_api:90 - 加载上次更新时间: 2025-09-18 07:53:49
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:30.323 | INFO | news_api:283 - 上次更新时间: 2025-09-18 07:53:49
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:30.323 | INFO | news_api:286 - 开始获取RSS源数据...
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:30.765 | DEBUG | news_api:126 - 成功获取 https://www.chinanews.com.cn/rss/finance.xml 的RSS数据
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:30.777 | DEBUG | news_api:126 - 成功获取 https://www.chinanews.com.cn/rss/china.xml 的RSS数据
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:30.786 | DEBUG | news_api:126 - 成功获取 https://www.chinanews.com.cn/rss/world.xml 的RSS数据
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.083 | DEBUG | news_api:126 - 成功获取 https://www.chinanews.com.cn/rss/scroll-news.xml 的RSS数据
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.085 | INFO | news_api:153 - RSS源获取完成,成功获取 4/4 个源
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.086 | INFO | news_api:289 - 获取完成,耗时: 0.76秒
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.086 | INFO | news_api:210 - 开始处理 RSS 源: https://www.chinanews.com.cn/rss/finance.xml
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.086 | DEBUG | news_api:227 - 处理条目 1: 双节假期临近 消费板块是否迎来上涨机遇?
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.087 | DEBUG | news_api:227 - 处理条目 2: “中国罗非鱼之都”广东茂名罗非鱼出口同比增逾两成
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.087 | DEBUG | news_api:227 - 处理条目 3: 今年以来广西单个最大新增用海面积项目获批
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.087 | DEBUG | news_api:227 - 处理条目 4: 首超10亿人次!河南文旅破圈背后的创新密码
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.087 | DEBUG | news_api:227 - 处理条目 5: 2025中国国际消费电子博览会在青岛举办
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.087 | DEBUG | news_api:227 - 处理条目 6: 四川经济总量连续跨过两个万亿元大关 实现历史性晋位
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.088 | DEBUG | news_api:227 - 处理条目 7: 广西最大工业城市抢抓东盟机遇 推进制造强市建设
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.088 | DEBUG | news_api:227 - 处理条目 8: 时令蔬果丰富居民“菜篮子” “小果子”撑起乡村振兴“大产业”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.088 | DEBUG | news_api:227 - 处理条目 9: AI点亮东博会 中国-东盟合作进入“数智时代”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.088 | DEBUG | news_api:227 - 处理条目 10: (活力中国调研行)盐城港滨海港区:“港口+产业+能源”三位一体打造沿海综合枢纽港
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.088 | DEBUG | news_api:227 - 处理条目 11: 【两点一存耀华夏】甘肃庆阳:革命老区插上数字化“翅膀”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.088 | DEBUG | news_api:227 - 处理条目 12: (活力中国调研行)探访全国最大的液化天然气能源枢纽站:10个“气墩墩”绿色能源送四方
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.089 | DEBUG | news_api:227 - 处理条目 13: 我国科技创新能力稳步提升
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.089 | DEBUG | news_api:227 - 处理条目 14: 厦门机场今年出入境客流破300万人次 外籍旅客超71万人次
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.089 | DEBUG | news_api:227 - 处理条目 15: 中外记者走进山东济南未来产业 体验科技力量
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.089 | DEBUG | news_api:227 - 处理条目 16: 中巴(西)财金分委会第十一次会议举行
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.089 | DEBUG | news_api:227 - 处理条目 17: 小米汽车科技有限公司召回部分SU7标准版电动汽车
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.089 | DEBUG | news_api:227 - 处理条目 18: 【新思想引领新征程·非凡“十四五”】从跟跑到领跑 中国新能源汽车迈上新台阶
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.090 | DEBUG | news_api:227 - 处理条目 19: 9部门发文支持一刻钟便民生活圈建设扩围升级
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.090 | DEBUG | news_api:227 - 处理条目 20: 何猷君:积极参与中国—东盟电竞发展浪潮
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.090 | DEBUG | news_api:227 - 处理条目 21: 广西北部湾港再添一条至中东的滚装新航线
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.090 | DEBUG | news_api:227 - 处理条目 22: 数智赋能发展 第22届东博会签约155个项目
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.091 | DEBUG | news_api:227 - 处理条目 23: 中国AI企业共拓东盟人工智能市场“蓝海”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.091 | DEBUG | news_api:227 - 处理条目 24: 工信部有关负责人解读《轻工业稳增长工作方案(2025—2026年)》
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.091 | DEBUG | news_api:227 - 处理条目 25: 三部门印发轻工业稳增长工作方案 助力行业持续回升向好
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.091 | DEBUG | news_api:227 - 处理条目 26: 今年前8个月全国制造业税收收入同比增长5%以上
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.091 | DEBUG | news_api:227 - 处理条目 27: 辽宁省数据局副局长刘洋:数据要素应用让群众跑腿变数据跑路
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.093 | DEBUG | news_api:227 - 处理条目 28: 海南自贸港数据安全有序流动 游戏、短剧出海迎国际化发展
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.093 | DEBUG | news_api:227 - 处理条目 29: 浙非深化电商合作 “数字丝路”推动互利共赢
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.093 | DEBUG | news_api:227 - 处理条目 30: 首届老中电力技术论坛在老挝纳塞通变电站举办
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.111 | DEBUG | mysql_agent:164 - 已建立连接,准备插入数据到 collector_rss_subscriptions
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.113 | DEBUG | mysql_agent:170 - 表 collector_rss_subscriptions 包含以下列:['id', '文章标题', '文章链接', '文章摘要', '发布时间', '来源URL', '创建时间', '更新时间']
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.121 | DEBUG | mysql_agent:196 - 表 collector_rss_subscriptions 的过滤后DataFrame:共 30 行待插入
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.326 | INFO | mysql_agent:282 - 表 collector_rss_subscriptions 插入结果汇总
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ total_to_insert: 30
|
||||||
|
→ total_inserted: 30
|
||||||
|
→ total_duplicates: 0
|
||||||
|
→ total_failed: 0
|
||||||
|
→ failed_records_count: 0
|
||||||
|
2025-09-19 13:57:31.326 | INFO | news_api:251 - 成功写入 30/30 条记录
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.326 | INFO | news_api:210 - 开始处理 RSS 源: https://www.chinanews.com.cn/rss/china.xml
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.327 | DEBUG | news_api:227 - 处理条目 1: 国庆中秋假期临近 多地创新文旅消费新场景
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.327 | DEBUG | news_api:227 - 处理条目 2: 生态环境部:将重点打击非法拆解废动力电池等“新三样”固体废物
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.327 | DEBUG | news_api:227 - 处理条目 3: 生态环境部:我国已建成全球规模最大的生态环境监测网络
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.327 | DEBUG | news_api:227 - 处理条目 4: 中央生态环保督察受理转办35万件群众举报 绝大多数已办结或阶段性办结
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.327 | DEBUG | news_api:227 - 处理条目 5: 习近平致中国致公党成立100周年的贺信
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.327 | DEBUG | news_api:227 - 处理条目 6: 习近平致信祝贺中国致公党成立100周年
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.327 | DEBUG | news_api:227 - 处理条目 7: 存在偷逃税等问题,1名主播、两家MCN被通报!
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.328 | DEBUG | news_api:227 - 处理条目 8: 生态环境部:风电、太阳能发电装机总量已提前完成2030年国家自主贡献目标
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.328 | DEBUG | news_api:227 - 处理条目 9: 生态环境部:加强准入管理 推动产业结构优化调整
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.328 | DEBUG | news_api:227 - 处理条目 10: 今年以来,全国生态环境质量延续持续向好态势
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.328 | DEBUG | news_api:227 - 处理条目 11: 生态环境部:基本建立了全域覆盖的生态环境分区管控体系
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.329 | DEBUG | news_api:227 - 处理条目 12: 我国陆域生态保护红线面积占比已超30%
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.329 | DEBUG | news_api:227 - 处理条目 13: 广西—文莱经济走廊建设推动各领域合作持续拓展
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.329 | DEBUG | news_api:227 - 处理条目 14: 生态环境部:“十四五”期间淘汰高排放车辆近2000万辆
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.329 | DEBUG | news_api:227 - 处理条目 15: 我国建成全球规模最大的碳排放权交易市场
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.330 | DEBUG | news_api:227 - 处理条目 16: 汇聚国内外资深专家学者 香山论坛首设“高端对话”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.330 | DEBUG | news_api:227 - 处理条目 17: “人类和平与发展的崇高事业必将胜利!”——习近平总书记重要讲话揭示历史前进的必然逻辑
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.330 | DEBUG | news_api:227 - 处理条目 18: 上海:发挥统一战线法宝作用 助力民营经济发展壮大
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.330 | DEBUG | news_api:227 - 处理条目 19: 东盟秘书长高金洪:中国与东盟双边贸易额将实现大幅跨越
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.331 | DEBUG | news_api:227 - 处理条目 20: 学习新语|九一八,铭记白山黑水间的抗联英雄
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.331 | DEBUG | news_api:227 - 处理条目 21: 贵州省自然资源厅党委委员、副厅长高玉平接受审查调查
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.331 | DEBUG | news_api:227 - 处理条目 22: 河南省信阳市政府原副市长杨淑萍接受审查调查
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.331 | DEBUG | news_api:227 - 处理条目 23: 湖南省高速公路集团原副总经理王辉扬被开除党籍
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.332 | DEBUG | news_api:227 - 处理条目 24: 互联网大厂持续反腐
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.332 | DEBUG | news_api:227 - 处理条目 25: 为困难退役军人排忧解难 “情暖老兵·关爱尊崇”专项行动启动
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.332 | DEBUG | news_api:227 - 处理条目 26: 跳水运动员遭网暴案被公安部列为打击整治网络违法犯罪典型案例
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.332 | DEBUG | news_api:227 - 处理条目 27: 【同心声影】侨海报国百年路 肝胆相照启新程
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.333 | DEBUG | news_api:227 - 处理条目 28: 我国现行地方性法规已达1.4万余件 地方立法“小快灵”带来哪些改变
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.333 | DEBUG | news_api:227 - 处理条目 29: “台北快轮”迎1000航次往返 畅通岚台“黄金通道”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.334 | DEBUG | news_api:227 - 处理条目 30: 天津打造《信仰的颜色》艺术“大思政课”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.336 | DEBUG | mysql_agent:164 - 已建立连接,准备插入数据到 collector_rss_subscriptions
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.338 | DEBUG | mysql_agent:170 - 表 collector_rss_subscriptions 包含以下列:['id', '文章标题', '文章链接', '文章摘要', '发布时间', '来源URL', '创建时间', '更新时间']
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.340 | DEBUG | mysql_agent:196 - 表 collector_rss_subscriptions 的过滤后DataFrame:共 30 行待插入
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.518 | INFO | mysql_agent:282 - 表 collector_rss_subscriptions 插入结果汇总
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ total_to_insert: 30
|
||||||
|
→ total_inserted: 30
|
||||||
|
→ total_duplicates: 0
|
||||||
|
→ total_failed: 0
|
||||||
|
→ failed_records_count: 0
|
||||||
|
2025-09-19 13:57:31.519 | INFO | news_api:251 - 成功写入 30/30 条记录
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.519 | INFO | news_api:210 - 开始处理 RSS 源: https://www.chinanews.com.cn/rss/world.xml
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.519 | DEBUG | news_api:227 - 处理条目 1: 国际最新研究:南美发现首批保存昆虫琥珀沉积物
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.520 | DEBUG | news_api:227 - 处理条目 2: 巴基斯坦西南部发生两起袭击事件造成8死23伤
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.520 | DEBUG | news_api:227 - 处理条目 3: 美媒:美政府请求最高法院允许其解雇美联储理事库克
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.520 | DEBUG | news_api:227 - 处理条目 4: 意大利车手在军舰甲板上创造“最快船载汽车”世界纪录
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.520 | DEBUG | news_api:227 - 处理条目 5: 加沙地带和约旦河西岸多名以军士兵遇袭伤亡
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.520 | DEBUG | news_api:227 - 处理条目 6: 金正恩指导无人武器装备性能试验 强调发展人工智能技术
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.520 | DEBUG | news_api:227 - 处理条目 7: 最新气候变化研究:野火烟雾造成超额和过早死亡人数预计会增加
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.521 | DEBUG | news_api:227 - 处理条目 8: 2025中比运河城市文化交流对话活动在布鲁塞尔举行
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.521 | DEBUG | news_api:227 - 处理条目 9: 法国超50万人举行罢工 反对政府财政紧缩方案
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.521 | DEBUG | news_api:227 - 处理条目 10: 电影《731》澳大利亚首映活动在悉尼举行
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.521 | DEBUG | news_api:227 - 处理条目 11: 中国常驻日内瓦代表团举办人人享有无障碍对话会
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.521 | DEBUG | news_api:227 - 处理条目 12: 《铭记和平——纪念世界反法西斯战争暨中国人民抗战胜利80周年、韩国光复80周年中韩书画展》在首尔开幕
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.522 | DEBUG | news_api:227 - 处理条目 13: 中国驻纽约总领馆举行国庆76周年招待会
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.522 | DEBUG | news_api:227 - 处理条目 14: 李在明支持率反弹至60%
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.522 | DEBUG | news_api:227 - 处理条目 15: 俄总统办公厅副主任被免职 曾是普京最亲密顾问之一
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.522 | DEBUG | news_api:227 - 处理条目 16: 美国佛罗里达州一男子在乘坐过山车后死亡
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.523 | DEBUG | news_api:227 - 处理条目 17: 法国发生多行业罢工 旨在反对政府财政紧缩计划
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.523 | DEBUG | news_api:227 - 处理条目 18: 未取得明显成果 韩国贸易代表结束访美回国
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.523 | DEBUG | news_api:227 - 处理条目 19: 南非央行维持基准利率在7%不变
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.523 | DEBUG | news_api:227 - 处理条目 20: 美参议院一次性表决通过48名特朗普政府提名人选
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.524 | DEBUG | news_api:227 - 处理条目 21: 特朗普反对英国承认巴勒斯坦国计划
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.524 | DEBUG | news_api:227 - 处理条目 22: 特朗普结束访英返美前 因直升机故障改乘备用机
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.524 | DEBUG | news_api:227 - 处理条目 23: 安理会未通过加沙停火决议草案 中方:非常失望
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.524 | DEBUG | news_api:227 - 处理条目 24: 美国再次一票否决加沙停火决议草案
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.525 | DEBUG | news_api:227 - 处理条目 25: 堪察加东岸附近海域发生7.8级地震
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.525 | DEBUG | news_api:227 - 处理条目 26: 泰国总理阿努廷承诺4个月内推动经济见效
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.525 | DEBUG | news_api:227 - 处理条目 27: 马来西亚交通部长:“空中丝路”助力马打造区域货运枢纽
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.525 | DEBUG | news_api:227 - 处理条目 28: 示威平息后雅加达经贸与文化活动再度升温
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.525 | DEBUG | news_api:227 - 处理条目 29: 世卫称加沙北部医院濒临崩溃 人道灾难必须立即结束
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.525 | DEBUG | news_api:227 - 处理条目 30: 外媒:乌军称袭击俄罗斯伏尔加格勒炼油厂
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.529 | DEBUG | mysql_agent:164 - 已建立连接,准备插入数据到 collector_rss_subscriptions
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.530 | DEBUG | mysql_agent:170 - 表 collector_rss_subscriptions 包含以下列:['id', '文章标题', '文章链接', '文章摘要', '发布时间', '来源URL', '创建时间', '更新时间']
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.531 | DEBUG | mysql_agent:196 - 表 collector_rss_subscriptions 的过滤后DataFrame:共 30 行待插入
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.691 | INFO | mysql_agent:282 - 表 collector_rss_subscriptions 插入结果汇总
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ total_to_insert: 30
|
||||||
|
→ total_inserted: 30
|
||||||
|
→ total_duplicates: 0
|
||||||
|
→ total_failed: 0
|
||||||
|
→ failed_records_count: 0
|
||||||
|
2025-09-19 13:57:31.692 | INFO | news_api:251 - 成功写入 30/30 条记录
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.692 | INFO | news_api:210 - 开始处理 RSS 源: https://www.chinanews.com.cn/rss/scroll-news.xml
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.692 | DEBUG | news_api:227 - 处理条目 1: “增肌神器”暗藏激素陷阱
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 2: 宋人茶肆里的世俗生活
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 3: 流感疫苗怎么选、何时打?
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 4: 国庆中秋假期临近 多地创新文旅消费新场景
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 5: 侨批:漂洋过海的信与银
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 6: 加强一体联动 推进技能型高校产教融合
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 7: 生态环境部:将重点打击非法拆解废动力电池等“新三样”固体废物
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 8: 国际最新研究:南美发现首批保存昆虫琥珀沉积物
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 9: 云海肴“85后”创始人赵晗去世
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.693 | DEBUG | news_api:227 - 处理条目 10: 在教室私装监控 警惕“育人”变“控人”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.694 | DEBUG | news_api:227 - 处理条目 11: 生态环境部:我国已建成全球规模最大的生态环境监测网络
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.694 | DEBUG | news_api:227 - 处理条目 12: 深圳鼓励外卖员随手拍“黑餐馆”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.694 | DEBUG | news_api:227 - 处理条目 13: 教室装监控被举报 该有的边界感要重拾
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.695 | DEBUG | news_api:227 - 处理条目 14: 戏曲正破圈而来 以另一种方式被打开
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.695 | DEBUG | news_api:227 - 处理条目 15: 金融知识小课堂丨警惕防不胜防的移动应用消费陷阱
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.695 | DEBUG | news_api:227 - 处理条目 16: 大闸蟹销售“熔断机制”,直击行业假冒痛点
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.695 | DEBUG | news_api:227 - 处理条目 17: 金融知识小课堂丨识破虚假投资理财
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.696 | DEBUG | news_api:227 - 处理条目 18: 在历史时空中重温台山籍侨胞的浓厚乡情
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.696 | DEBUG | news_api:227 - 处理条目 19: 得了脂肪肝要怎么吃?营养专家来支招
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.696 | DEBUG | news_api:227 - 处理条目 20: 青海海西州就“一‘矿霸’非法填埋万吨危废”事件成立调查组
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.696 | DEBUG | news_api:227 - 处理条目 21: 双节假期临近 消费板块是否迎来上涨机遇?
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.697 | DEBUG | news_api:227 - 处理条目 22: 中经评论:“人工智能+制造”不是简单叠加
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.697 | DEBUG | news_api:227 - 处理条目 23: 巴基斯坦西南部发生两起袭击事件造成8死23伤
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.697 | DEBUG | news_api:227 - 处理条目 24: 金观平:因城施策破解千城一面
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.697 | DEBUG | news_api:227 - 处理条目 25: 书香引入商圈,除了“种草”还有什么
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.698 | DEBUG | news_api:227 - 处理条目 26: 海外中文学校帮华裔青年“寻根” 为外国学生“开窗”
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.698 | DEBUG | news_api:227 - 处理条目 27: 中央生态环保督察受理转办35万件群众举报 绝大多数已办结或阶段性办结
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.698 | DEBUG | news_api:227 - 处理条目 28: 致命的“化骨水”中毒,如何防范和急救?
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.699 | DEBUG | news_api:227 - 处理条目 29: 习近平致中国致公党成立100周年的贺信
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.699 | DEBUG | news_api:227 - 处理条目 30: “中国罗非鱼之都”广东茂名罗非鱼出口同比增逾两成
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.701 | DEBUG | mysql_agent:164 - 已建立连接,准备插入数据到 collector_rss_subscriptions
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.703 | DEBUG | mysql_agent:170 - 表 collector_rss_subscriptions 包含以下列:['id', '文章标题', '文章链接', '文章摘要', '发布时间', '来源URL', '创建时间', '更新时间']
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.704 | DEBUG | mysql_agent:196 - 表 collector_rss_subscriptions 的过滤后DataFrame:共 30 行待插入
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
2025-09-19 13:57:31.724 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 3
|
||||||
|
→ error_message: "Duplicate entry '国庆中秋假期临近 多地创新文旅消费新场景-2025-' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '国庆中秋假期临近 多地创新文旅消费新场景...', '文章链接': 'http://www.chinanews.com/gn/2025/09-19/10485196.shtml...', '文章摘要': '国庆中秋假期临近 多地创新文旅消费新场景 迎接客流高峰...', '发布时间': '2025-09-19 05:51:25...', '来源URL': 'https:/...
|
||||||
|
2025-09-19 13:57:31.737 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 6
|
||||||
|
→ error_message: "Duplicate entry '生态环境部:将重点打击非法拆解废动力电池等â' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '生态环境部:将重点打击非法拆解废动力电池等“新三样”固体废物...', '文章链接': 'http://www.chinanews.com/gn/2025/09-19/10485183.shtml...', '文章摘要': '中新网9月19日电 国新办19日举行“高质量完成‘十四五’规划”系列主题新闻发布会,介绍以生态环境高水平保护推动高质量发展情况。...', '发布时...
|
||||||
|
2025-09-19 13:57:31.740 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 7
|
||||||
|
→ error_message: "Duplicate entry '国际最新研究:南美发现首批保存昆虫琥珀沉积ç' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '国际最新研究:南美发现首批保存昆虫琥珀沉积物...', '文章链接': 'http://www.chinanews.com/gj/2025/09-19/10485194.shtml...', '文章摘要': '中新网北京9月19日电 (记者 孙自法)施普林格·自然旗下专业学术期刊《通讯-地球与环境》最新发表一篇古生物学论文指出,研究人员在厄瓜多尔一个采石场发现南美首批含有...
|
||||||
|
2025-09-19 13:57:31.753 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 10
|
||||||
|
→ error_message: "Duplicate entry '生态环境部:我国已建成全球规模最大的生态环å' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '生态环境部:我国已建成全球规模最大的生态环境监测网络...', '文章链接': 'http://www.chinanews.com/gn/2025/09-19/10485174.shtml...', '文章摘要': '中新网9月19日电 国新办19日举行“高质量完成‘十四五’规划”系列主题新闻发布会,介绍以生态环境高水平保护推动高质量发展情况。...', '发布时间': ...
|
||||||
|
2025-09-19 13:57:31.802 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 20
|
||||||
|
→ error_message: "Duplicate entry '双节假期临近 消费板块是否迎来上涨机遇?-2025-' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '双节假期临近 消费板块是否迎来上涨机遇?...', '文章链接': 'http://www.chinanews.com/cj/2025/09-19/10485187.shtml...', '文章摘要': '央广网北京9月19日消息(记者蔡军)据中央广播电视总台经济之声《交易实况》报道,9月18日,消费股中的餐饮旅游板块尾盘拉升,曲江文旅、云南旅游涨停,西安饮食、西安旅游、...
|
||||||
|
2025-09-19 13:57:31.810 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 22
|
||||||
|
→ error_message: "Duplicate entry '巴基斯坦西南部发生两起袭击事件造成8死23伤-202' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '巴基斯坦西南部发生两起袭击事件造成8死23伤...', '文章链接': 'http://www.chinanews.com/gj/2025/09-19/10485170.shtml...', '文章摘要': '中新社北京9月19日电 伊斯兰堡消息:巴基斯坦官员18日称,该国西南部俾路支省当日发生两起袭击事件,造成8人死亡、23人受伤。...', '发布时间': '2025...
|
||||||
|
2025-09-19 13:57:31.827 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 26
|
||||||
|
→ error_message: "Duplicate entry '中央生态环保督察受理转办35万件群众举报 绝大å' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '中央生态环保督察受理转办35万件群众举报 绝大多数已办结或阶段性办结...', '文章链接': 'http://www.chinanews.com/gn/2025/09-19/10485172.shtml...', '文章摘要': '中新网9月19日电 国新办19日举行“高质量完成‘十四五’规划”系列主题新闻发布会,介绍以生态环境高水平保护推动高质量发展情况。会上,生态环...
|
||||||
|
2025-09-19 13:57:31.836 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 28
|
||||||
|
→ error_message: "Duplicate entry '习近平致中国致公党成立100周年的贺信-2025-09-19 0' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '习近平致中国致公党成立100周年的贺信...', '文章链接': 'http://www.chinanews.com/gn/2025/09-19/10485171.shtml...', '文章摘要': '新华社北京9月19日电...', '发布时间': '2025-09-19 05:05:34...', '来源URL': 'https://www.chinanews.co...
|
||||||
|
2025-09-19 13:57:31.839 | WARNING | mysql_agent:241 - 表 collector_rss_subscriptions 中跳过重复记录
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ index: 29
|
||||||
|
→ error_message: "Duplicate entry '“中国罗非鱼之都”广东茂名罗非鱼出口同比增é' for key 'collector_rss_subscriptions.idx_title_pubtime'"
|
||||||
|
→ record: {'文章标题': '“中国罗非鱼之都”广东茂名罗非鱼出口同比增逾两成...', '文章链接': 'http://www.chinanews.com/cj/2025/09-19/10485167.shtml...', '文章摘要': '中新社广东茂名9月19日电 (记者 梁盛)记者19日从广东茂名市农业农村局了解到,今年上半年,该市罗非鱼产量14.48万吨,同比增长7.12%,罗非鱼及其产品出...
|
||||||
|
2025-09-19 13:57:31.839 | INFO | mysql_agent:282 - 表 collector_rss_subscriptions 插入结果汇总
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ total_to_insert: 30
|
||||||
|
→ total_inserted: 21
|
||||||
|
→ total_duplicates: 9
|
||||||
|
→ total_failed: 0
|
||||||
|
→ failed_records_count: 9
|
||||||
|
2025-09-19 13:57:31.840 | ERROR | mysql_agent:293 - 表 collector_rss_subscriptions 插入失败记录详情
|
||||||
|
→ module: 'MySQLAgent(Windows)'
|
||||||
|
→ failed_records_summary: [{'index': 3, 'type': 'duplicate', 'error_code': 1062, 'error_message': "Duplicate entry '国庆中秋假期临近 多地创新文旅消费新场景-2025-' for key 'collector_rss_subscriptions.idx_title_pubtime'"}, {'index': 6, 'type':...
|
||||||
|
→ detailed_failed_records: [{'index': 3, 'type': 'duplicate', 'error_code': 1062, 'error_message': "Duplicate entry '国庆中秋假期临近 多地创新文旅消费新场景-2025-' for key 'collector_rss_subscriptions.idx_title_pubtime'", 'record': {'文章标题': '国...
|
||||||
|
2025-09-19 13:57:31.841 | INFO | news_api:251 - 成功写入 21/30 条记录
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.842 | DEBUG | news_api:106 - 已保存本次更新时间: 2025-09-19 05:54:27
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
2025-09-19 13:57:31.842 | INFO | news_api:301 - 本次最新更新时间: 2025-09-19 05:54:27
|
||||||
|
→ module: 'NewsAPIClient'
|
||||||
|
|||||||
@@ -65258,3 +65258,5 @@
|
|||||||
|
|
||||||
2025-09-18 15:46:27.640 | ERROR | news_api:259 - 数据库写入失败: MySQLAgent.insert_from_df() got an unexpected keyword argument 'replace'
|
2025-09-18 15:46:27.640 | ERROR | news_api:259 - 数据库写入失败: MySQLAgent.insert_from_df() got an unexpected keyword argument 'replace'
|
||||||
|
|
||||||
|
2025-09-19 13:57:31.840 | ERROR | mysql_agent:293 - 表 collector_rss_subscriptions 插入失败记录详情
|
||||||
|
|
||||||
|
|||||||
+30
-13
File diff suppressed because one or more lines are too long
+137
-97
@@ -78,16 +78,16 @@ class MySQLAgent:
|
|||||||
if platform.system() == 'Darwin' and self.config.get('ssl'):
|
if platform.system() == 'Darwin' and self.config.get('ssl'):
|
||||||
conn.ping(reconnect=True)
|
conn.ping(reconnect=True)
|
||||||
|
|
||||||
self.log.trace("Database connection obtained")
|
self.log.trace("获取数据库连接成功")
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_msg = str(e)
|
error_msg = str(e)
|
||||||
if platform.system() == 'Windows' and "timed out" in error_msg:
|
if platform.system() == 'Windows' and "timed out" in error_msg:
|
||||||
self.log.warning("Windows connection timeout, retrying...")
|
self.log.warning("Windows连接超时,正在重试...")
|
||||||
return self._retry_connection()
|
return self._retry_connection()
|
||||||
|
|
||||||
self.log.error("Connection failed", error=error_msg, exc_info=True)
|
self.log.error("连接失败", error=error_msg, exc_info=True)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def _retry_connection(self, max_retries: int = 3) -> Any | None:
|
def _retry_connection(self, max_retries: int = 3) -> Any | None:
|
||||||
@@ -95,7 +95,7 @@ class MySQLAgent:
|
|||||||
for attempt in range(max_retries):
|
for attempt in range(max_retries):
|
||||||
try:
|
try:
|
||||||
conn = pymysql.connect(**self.config)
|
conn = pymysql.connect(**self.config)
|
||||||
self.log.info(f"Connection established after {attempt + 1} attempts")
|
self.log.info(f"经过 {attempt + 1} 次尝试后成功建立连接")
|
||||||
return conn
|
return conn
|
||||||
except Exception:
|
except Exception:
|
||||||
if attempt == max_retries - 1:
|
if attempt == max_retries - 1:
|
||||||
@@ -107,7 +107,7 @@ class MySQLAgent:
|
|||||||
parse_dates: Union[List[str], bool] = True) -> pd.DataFrame:
|
parse_dates: Union[List[str], bool] = True) -> pd.DataFrame:
|
||||||
"""执行SQL查询并返回DataFrame(原有逻辑完全保留)"""
|
"""执行SQL查询并返回DataFrame(原有逻辑完全保留)"""
|
||||||
try:
|
try:
|
||||||
self.log.debug("Executing SQL query", sql=sql)
|
self.log.debug("执行SQL查询", sql=sql)
|
||||||
|
|
||||||
# 获取连接并确保字符集方法存在
|
# 获取连接并确保字符集方法存在
|
||||||
conn = self.get_connection()
|
conn = self.get_connection()
|
||||||
@@ -124,49 +124,50 @@ class MySQLAgent:
|
|||||||
|
|
||||||
# 执行查询
|
# 执行查询
|
||||||
df = pd.read_sql(sql, engine, params=params, parse_dates=parse_dates)
|
df = pd.read_sql(sql, engine, params=params, parse_dates=parse_dates)
|
||||||
self.log.info("Query executed successfully", rows=len(df))
|
self.log.info("查询执行成功", 行数=len(df))
|
||||||
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error("SQL query failed", sql=sql, params=params, error=str(e), exc_info=True)
|
self.log.error("SQL查询失败", sql=sql, params=params, error=str(e), exc_info=True)
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
if 'engine' in locals():
|
if 'engine' in locals():
|
||||||
engine.dispose()
|
engine.dispose()
|
||||||
|
|
||||||
def insert_from_df(self, table_name: str, df: pd.DataFrame,
|
def insert_from_df(self, table_name: str, df: pd.DataFrame,
|
||||||
chunk_size: int = 1000, replace: bool = False, # 保留replace参数
|
chunk_size: int = 1000, replace: bool = False,
|
||||||
ignore_duplicates: bool = None) -> int: # 新增ignore_duplicates参数
|
ignore_duplicates: bool = None) -> int:
|
||||||
"""
|
"""
|
||||||
兼容旧接口的通用插入方法:保留replace参数,同时支持新的ignore_duplicates
|
兼容旧接口的通用插入方法:保留replace参数,同时支持新的ignore_duplicates
|
||||||
自动处理重复数据,对所有数据源通用
|
自动处理重复数据,对所有数据源通用,插入失败的数据会通过日志记录
|
||||||
"""
|
"""
|
||||||
# 【兼容性处理】如果未指定ignore_duplicates,用replace参数推导(replace=True时不忽略重复)
|
# 【兼容性处理】如果未指定ignore_duplicates,用replace参数推导
|
||||||
if ignore_duplicates is None:
|
if ignore_duplicates is None:
|
||||||
ignore_duplicates = not replace # 旧逻辑中replace=True表示替换,即不忽略重复
|
ignore_duplicates = not replace # 旧逻辑中replace=True表示替换,即不忽略重复
|
||||||
|
|
||||||
if df.empty:
|
if df.empty:
|
||||||
self.log.warning("Attempted to insert empty DataFrame", table=table_name)
|
self.log.warning("尝试插入空的DataFrame", table=table_name)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
conn = None
|
conn = None
|
||||||
cursor = None
|
cursor = None
|
||||||
total_inserted = 0
|
total_inserted = 0
|
||||||
total_duplicated = 0
|
total_duplicates = 0
|
||||||
total_failed = 0
|
total_failed = 0
|
||||||
|
failed_records = [] # 存储所有失败的记录
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 1. 建立数据库连接
|
# 1. 建立数据库连接
|
||||||
conn = self.get_connection()
|
conn = self.get_connection()
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
self.log.debug(f"Established connection for inserting into {table_name}")
|
self.log.debug(f"已建立连接,准备插入数据到 {table_name}")
|
||||||
|
|
||||||
# 2. 获取数据库表的实际列名
|
# 2. 获取数据库表的实际列名
|
||||||
cursor.execute(f"SHOW COLUMNS FROM `{table_name}`")
|
cursor.execute(f"SHOW COLUMNS FROM `{table_name}`")
|
||||||
columns_info = cursor.fetchall()
|
columns_info = cursor.fetchall()
|
||||||
db_columns = [col[0] for col in columns_info]
|
db_columns = [col[0] for col in columns_info]
|
||||||
self.log.debug(f"Table {table_name} has columns: {db_columns}")
|
self.log.debug(f"表 {table_name} 包含以下列:{db_columns}")
|
||||||
|
|
||||||
# 3. 数据预处理:统一处理空值
|
# 3. 数据预处理:统一处理空值
|
||||||
cleaned_df = df.replace(
|
cleaned_df = df.replace(
|
||||||
@@ -181,19 +182,19 @@ class MySQLAgent:
|
|||||||
|
|
||||||
if unmatched_columns:
|
if unmatched_columns:
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
f"Table {table_name} dropping unmatched columns",
|
f"表 {table_name} 中存在不匹配的列,已自动丢弃",
|
||||||
unmatched_columns=unmatched_columns,
|
unmatched_columns=unmatched_columns,
|
||||||
count=len(unmatched_columns)
|
count=len(unmatched_columns)
|
||||||
)
|
)
|
||||||
|
|
||||||
if not matched_columns:
|
if not matched_columns:
|
||||||
self.log.warning(f"No matched columns for {table_name}, abort insertion")
|
self.log.warning(f"表 {table_name} 没有匹配的列,终止插入操作")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
filtered_df = cleaned_df[matched_columns].copy()
|
filtered_df = cleaned_df[matched_columns].copy()
|
||||||
total_to_insert = len(filtered_df)
|
total_to_insert = len(filtered_df)
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
f"Filtered DataFrame for {table_name}: {total_to_insert} rows to insert"
|
f"表 {table_name} 的过滤后DataFrame:共 {total_to_insert} 行待插入"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 5. 处理复杂类型(dict/list转JSON)
|
# 5. 处理复杂类型(dict/list转JSON)
|
||||||
@@ -203,7 +204,7 @@ class MySQLAgent:
|
|||||||
).any()
|
).any()
|
||||||
|
|
||||||
if has_complex_type:
|
if has_complex_type:
|
||||||
self.log.debug(f"Column {col} in {table_name} has complex type, converting to JSON")
|
self.log.debug(f"表 {table_name} 中的 {col} 列包含复杂类型,正在转换为JSON")
|
||||||
filtered_df.loc[:, col] = filtered_df[col].apply(
|
filtered_df.loc[:, col] = filtered_df[col].apply(
|
||||||
lambda x: json.dumps(x, ensure_ascii=False) if x is not None else x
|
lambda x: json.dumps(x, ensure_ascii=False) if x is not None else x
|
||||||
)
|
)
|
||||||
@@ -212,7 +213,7 @@ class MySQLAgent:
|
|||||||
columns_str = ', '.join([f"`{col}`" for col in filtered_df.columns])
|
columns_str = ', '.join([f"`{col}`" for col in filtered_df.columns])
|
||||||
placeholders = ', '.join(['%s'] * len(filtered_df.columns))
|
placeholders = ', '.join(['%s'] * len(filtered_df.columns))
|
||||||
insert_sql = f"INSERT INTO `{table_name}` ({columns_str}) VALUES ({placeholders})"
|
insert_sql = f"INSERT INTO `{table_name}` ({columns_str}) VALUES ({placeholders})"
|
||||||
self.log.trace(f"Generated insert SQL for {table_name}: {insert_sql}")
|
self.log.trace(f"为表 {table_name} 生成的插入SQL:{insert_sql}")
|
||||||
|
|
||||||
# 7. 逐条插入(确保能捕获单条重复错误)
|
# 7. 逐条插入(确保能捕获单条重复错误)
|
||||||
records = filtered_df.to_dict('records')
|
records = filtered_df.to_dict('records')
|
||||||
@@ -226,34 +227,50 @@ class MySQLAgent:
|
|||||||
|
|
||||||
if (i + 1) % 100 == 0:
|
if (i + 1) % 100 == 0:
|
||||||
self.log.trace(
|
self.log.trace(
|
||||||
f"Inserted {i + 1}/{total_to_insert} rows into {table_name}"
|
f"已向表 {table_name} 插入 {i + 1}/{total_to_insert} 行数据"
|
||||||
)
|
)
|
||||||
|
|
||||||
except MySQLError as e:
|
except MySQLError as e:
|
||||||
# 8. 捕获重复错误(MySQL错误码1062)
|
# 8. 捕获重复错误(MySQL错误码1062)
|
||||||
if e.args[0] == 1062:
|
if e.args[0] == 1062:
|
||||||
total_duplicated += 1
|
total_duplicates += 1
|
||||||
short_record = {
|
short_record = {
|
||||||
k: (str(v)[:100] + '...') if isinstance(v, (str, dict, list)) else v
|
k: (str(v)[:100] + '...') if isinstance(v, (str, dict, list)) else v
|
||||||
for k, v in record.items()
|
for k, v in record.items()
|
||||||
}
|
}
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
f"Skipped duplicate record in {table_name}",
|
f"表 {table_name} 中跳过重复记录",
|
||||||
index=idx,
|
index=idx,
|
||||||
error_msg=e.args[1],
|
error_message=e.args[1],
|
||||||
record=short_record
|
record=short_record
|
||||||
)
|
)
|
||||||
|
# 记录重复的记录
|
||||||
|
failed_records.append({
|
||||||
|
'index': idx,
|
||||||
|
'type': 'duplicate',
|
||||||
|
'error_code': e.args[0],
|
||||||
|
'error_message': e.args[1],
|
||||||
|
'record': record
|
||||||
|
})
|
||||||
if not ignore_duplicates:
|
if not ignore_duplicates:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
# 其他数据库错误
|
# 其他数据库错误
|
||||||
total_failed += 1
|
total_failed += 1
|
||||||
|
# 记录失败的记录详情
|
||||||
|
failed_records.append({
|
||||||
|
'index': idx,
|
||||||
|
'type': 'error',
|
||||||
|
'error_code': e.args[0],
|
||||||
|
'error_message': e.args[1],
|
||||||
|
'record': record
|
||||||
|
})
|
||||||
self.log.error(
|
self.log.error(
|
||||||
f"Failed to insert record in {table_name}",
|
f"表 {table_name} 插入记录失败",
|
||||||
index=idx,
|
index=idx,
|
||||||
error_code=e.args[0],
|
error_code=e.args[0],
|
||||||
error_msg=e.args[1],
|
error_message=e.args[1],
|
||||||
record=record
|
record=record # 完整记录写入日志
|
||||||
)
|
)
|
||||||
if not ignore_duplicates:
|
if not ignore_duplicates:
|
||||||
raise
|
raise
|
||||||
@@ -261,13 +278,30 @@ class MySQLAgent:
|
|||||||
# 提交事务
|
# 提交事务
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
# 9. 插入结果统计
|
# 9. 插入结果统计,包括失败记录汇总
|
||||||
self.log.info(
|
self.log.info(
|
||||||
f"Insertion summary for {table_name}",
|
f"表 {table_name} 插入结果汇总",
|
||||||
total_to_insert=total_to_insert,
|
total_to_insert=total_to_insert,
|
||||||
total_inserted=total_inserted,
|
total_inserted=total_inserted,
|
||||||
total_duplicated=total_duplicated,
|
total_duplicates=total_duplicates,
|
||||||
total_failed=total_failed
|
total_failed=total_failed,
|
||||||
|
failed_records_count=len(failed_records)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 单独记录所有失败的数据详情
|
||||||
|
if failed_records:
|
||||||
|
self.log.error(
|
||||||
|
f"表 {table_name} 插入失败记录详情",
|
||||||
|
failed_records_summary=[
|
||||||
|
{
|
||||||
|
'index': r['index'],
|
||||||
|
'type': r['type'],
|
||||||
|
'error_code': r['error_code'],
|
||||||
|
'error_message': r['error_message']
|
||||||
|
} for r in failed_records
|
||||||
|
],
|
||||||
|
# 完整记录可以作为调试信息单独记录,避免日志过大
|
||||||
|
detailed_failed_records=failed_records
|
||||||
)
|
)
|
||||||
|
|
||||||
return total_inserted
|
return total_inserted
|
||||||
@@ -275,7 +309,13 @@ class MySQLAgent:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
if conn:
|
if conn:
|
||||||
conn.rollback()
|
conn.rollback()
|
||||||
self.log.error(f"Batch insertion failed for {table_name}", error=str(e), exc_info=True)
|
self.log.error(f"表 {table_name} 批量插入失败", error=str(e), exc_info=True)
|
||||||
|
# 记录事务回滚时的失败记录
|
||||||
|
if failed_records:
|
||||||
|
self.log.error(
|
||||||
|
f"表 {table_name} 事务回滚,已失败的记录",
|
||||||
|
failed_records=failed_records
|
||||||
|
)
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
if cursor:
|
if cursor:
|
||||||
@@ -296,7 +336,7 @@ class MySQLAgent:
|
|||||||
result = cursor.fetchone()
|
result = cursor.fetchone()
|
||||||
return result[0] if result else None
|
return result[0] if result else None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.warning(f"Failed to get primary key for {table_name}", error=str(e))
|
self.log.warning(f"获取表 {table_name} 的主键失败", error=str(e))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_table_detailed_info(self, table_name: str) -> Dict[str, Dict[str, Any]]:
|
def _get_table_detailed_info(self, table_name: str) -> Dict[str, Dict[str, Any]]:
|
||||||
@@ -319,7 +359,7 @@ class MySQLAgent:
|
|||||||
# 强制转换为列表,避免游标类型导致的解析问题
|
# 强制转换为列表,避免游标类型导致的解析问题
|
||||||
result_list = list(result)
|
result_list = list(result)
|
||||||
if not result_list:
|
if not result_list:
|
||||||
self.log.error("No columns found in table", table=table_name)
|
self.log.error("未在表中找到任何列", 表=table_name)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
schema = {}
|
schema = {}
|
||||||
@@ -334,16 +374,16 @@ class MySQLAgent:
|
|||||||
'max_length': max_length
|
'max_length': max_length
|
||||||
}
|
}
|
||||||
|
|
||||||
self.log.debug("Successfully fetched table schema",
|
self.log.debug("成功获取表结构信息",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
columns=list(schema.keys()))
|
列=list(schema.keys()))
|
||||||
return schema
|
return schema
|
||||||
finally:
|
finally:
|
||||||
cursor.close()
|
cursor.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error("Failed to get table detailed info",
|
self.log.error("获取表详细信息失败",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
error=str(e))
|
error=str(e))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@@ -358,10 +398,10 @@ class MySQLAgent:
|
|||||||
invalid_columns = [col for col in df_columns if col not in table_columns]
|
invalid_columns = [col for col in df_columns if col not in table_columns]
|
||||||
|
|
||||||
if invalid_columns:
|
if invalid_columns:
|
||||||
self.log.warning("Dropping invalid columns not present in table",
|
self.log.warning("丢弃表中不存在的无效列",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
invalid_columns=invalid_columns,
|
无效列=invalid_columns,
|
||||||
count=len(invalid_columns))
|
数量=len(invalid_columns))
|
||||||
|
|
||||||
cleaned_df = df[valid_columns].copy()
|
cleaned_df = df[valid_columns].copy()
|
||||||
if cleaned_df.empty:
|
if cleaned_df.empty:
|
||||||
@@ -378,11 +418,11 @@ class MySQLAgent:
|
|||||||
# 根据字段类型设置默认值
|
# 根据字段类型设置默认值
|
||||||
default_value = '' if data_type in ['varchar', 'char', 'text'] else None
|
default_value = '' if data_type in ['varchar', 'char', 'text'] else None
|
||||||
cleaned_df[col].fillna(default_value, inplace=True)
|
cleaned_df[col].fillna(default_value, inplace=True)
|
||||||
self.log.debug("Replaced null values",
|
self.log.debug("替换空值",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
column=col,
|
列=col,
|
||||||
default_value=default_value,
|
默认值=default_value,
|
||||||
count=cleaned_df[col].isnull().sum())
|
数量=cleaned_df[col].isnull().sum())
|
||||||
|
|
||||||
# 2.2 处理字符串类型的超长字段
|
# 2.2 处理字符串类型的超长字段
|
||||||
if data_type in ['varchar', 'char'] and max_length:
|
if data_type in ['varchar', 'char'] and max_length:
|
||||||
@@ -392,11 +432,11 @@ class MySQLAgent:
|
|||||||
too_long_mask = cleaned_df[col].str.len() > max_length
|
too_long_mask = cleaned_df[col].str.len() > max_length
|
||||||
if too_long_mask.any():
|
if too_long_mask.any():
|
||||||
cleaned_df.loc[too_long_mask, col] = cleaned_df.loc[too_long_mask, col].str.slice(0, max_length)
|
cleaned_df.loc[too_long_mask, col] = cleaned_df.loc[too_long_mask, col].str.slice(0, max_length)
|
||||||
self.log.warning("Truncated overlength values",
|
self.log.warning("截断超长值",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
column=col,
|
列=col,
|
||||||
max_length=max_length,
|
最大长度=max_length,
|
||||||
count=too_long_mask.sum())
|
数量=too_long_mask.sum())
|
||||||
|
|
||||||
# 2.3 处理日期时间类型
|
# 2.3 处理日期时间类型
|
||||||
if data_type in ['datetime', 'timestamp']:
|
if data_type in ['datetime', 'timestamp']:
|
||||||
@@ -404,10 +444,10 @@ class MySQLAgent:
|
|||||||
# 尝试转换为datetime类型
|
# 尝试转换为datetime类型
|
||||||
cleaned_df[col] = pd.to_datetime(cleaned_df[col])
|
cleaned_df[col] = pd.to_datetime(cleaned_df[col])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.warning("Failed to convert to datetime, using current time",
|
self.log.warning("转换为datetime失败,使用当前时间替代",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
column=col,
|
列=col,
|
||||||
error=str(e))
|
错误=str(e))
|
||||||
# 转换失败的用当前时间替代
|
# 转换失败的用当前时间替代
|
||||||
invalid_mask = pd.to_datetime(cleaned_df[col], errors='coerce').isna()
|
invalid_mask = pd.to_datetime(cleaned_df[col], errors='coerce').isna()
|
||||||
cleaned_df.loc[invalid_mask, col] = datetime.now()
|
cleaned_df.loc[invalid_mask, col] = datetime.now()
|
||||||
@@ -418,19 +458,19 @@ class MySQLAgent:
|
|||||||
key_columns: Union[str, List[str]]) -> int:
|
key_columns: Union[str, List[str]]) -> int:
|
||||||
"""使用DataFrame数据更新数据库表(原有逻辑完全保留)"""
|
"""使用DataFrame数据更新数据库表(原有逻辑完全保留)"""
|
||||||
if df.empty:
|
if df.empty:
|
||||||
self.log.warning("Attempted to update with empty DataFrame", table=table_name)
|
self.log.warning("尝试使用空的DataFrame进行更新", 表=table_name)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
self.log.debug("Preparing to update table from DataFrame",
|
self.log.debug("准备从DataFrame更新表数据",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
key_columns=key_columns,
|
关键字列=key_columns,
|
||||||
rows=len(df))
|
行数=len(df))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if isinstance(key_columns, str):
|
if isinstance(key_columns, str):
|
||||||
key_columns = [key_columns]
|
key_columns = [key_columns]
|
||||||
|
|
||||||
total_updated = 0
|
总更新数 = 0
|
||||||
with self.get_connection() as conn:
|
with self.get_connection() as conn:
|
||||||
with conn.cursor() as cursor:
|
with conn.cursor() as cursor:
|
||||||
# 获取表结构信息
|
# 获取表结构信息
|
||||||
@@ -442,11 +482,11 @@ class MySQLAgent:
|
|||||||
where_clause = ' AND '.join([f"{col}=%s" for col in key_columns])
|
where_clause = ' AND '.join([f"{col}=%s" for col in key_columns])
|
||||||
|
|
||||||
if not set_clause:
|
if not set_clause:
|
||||||
self.log.warning("No columns to update", table=table_name)
|
self.log.warning("没有可更新的列", 表=table_name)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
update_sql = f"UPDATE {table_name} SET {set_clause} WHERE {where_clause}"
|
update_sql = f"UPDATE {table_name} SET {set_clause} WHERE {where_clause}"
|
||||||
self.log.trace("Generated update SQL", sql=update_sql)
|
self.log.trace("生成的更新SQL", sql=update_sql)
|
||||||
|
|
||||||
# 准备数据
|
# 准备数据
|
||||||
update_data = []
|
update_data = []
|
||||||
@@ -457,17 +497,17 @@ class MySQLAgent:
|
|||||||
|
|
||||||
# 执行批量更新
|
# 执行批量更新
|
||||||
cursor.executemany(update_sql, update_data)
|
cursor.executemany(update_sql, update_data)
|
||||||
total_updated = cursor.rowcount
|
总更新数 = cursor.rowcount
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
self.log.info("Data updated successfully",
|
self.log.info("数据更新成功",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
rows_updated=total_updated)
|
更新行数=总更新数)
|
||||||
return total_updated
|
return 总更新数
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error("Data update failed",
|
self.log.error("数据更新失败",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
error=str(e),
|
error=str(e),
|
||||||
exc_info=True)
|
exc_info=True)
|
||||||
raise
|
raise
|
||||||
@@ -488,20 +528,20 @@ class MySQLAgent:
|
|||||||
dtype_str = str(dtype)
|
dtype_str = str(dtype)
|
||||||
sql_types[col] = type_mapping.get(dtype_str, 'TEXT')
|
sql_types[col] = type_mapping.get(dtype_str, 'TEXT')
|
||||||
|
|
||||||
self.log.debug("Mapped DataFrame types to SQL types",
|
self.log.debug("将DataFrame类型映射为SQL类型",
|
||||||
mappings=sql_types)
|
映射关系=sql_types)
|
||||||
return sql_types
|
return sql_types
|
||||||
|
|
||||||
def create_table_from_df(self, table_name: str, df: pd.DataFrame,
|
def create_table_from_df(self, table_name: str, df: pd.DataFrame,
|
||||||
primary_key: Union[str, List[str], None] = None) -> bool:
|
primary_key: Union[str, List[str], None] = None) -> bool:
|
||||||
"""根据DataFrame结构创建表(原有逻辑完全保留)"""
|
"""根据DataFrame结构创建表(原有逻辑完全保留)"""
|
||||||
if self.table_exists(table_name):
|
if self.table_exists(table_name):
|
||||||
self.log.warning("Table already exists", table=table_name)
|
self.log.warning("表已存在", 表=table_name)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.log.debug("Creating new table from DataFrame schema",
|
self.log.debug("根据DataFrame结构创建新表",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
columns=list(df.columns))
|
列=list(df.columns))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sql_types = self.df_to_sql_type(df)
|
sql_types = self.df_to_sql_type(df)
|
||||||
@@ -517,19 +557,19 @@ class MySQLAgent:
|
|||||||
pk_columns = [col for col in primary_key if col in sql_types]
|
pk_columns = [col for col in primary_key if col in sql_types]
|
||||||
if pk_columns:
|
if pk_columns:
|
||||||
columns_sql.append(f"PRIMARY KEY ({', '.join(pk_columns)})")
|
columns_sql.append(f"PRIMARY KEY ({', '.join(pk_columns)})")
|
||||||
self.log.trace("Set primary key",
|
self.log.trace("设置主键",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
primary_key=pk_columns)
|
主键=pk_columns)
|
||||||
|
|
||||||
create_sql = f"CREATE TABLE {table_name} (\n {',\n '.join(columns_sql)}\n)"
|
create_sql = f"CREATE TABLE {table_name} (\n {',\n '.join(columns_sql)}\n)"
|
||||||
|
|
||||||
self.execute_sql(create_sql)
|
self.execute_sql(create_sql)
|
||||||
self.log.info("Table created successfully", table=table_name)
|
self.log.info("表创建成功", 表=table_name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error("Failed to create table",
|
self.log.error("创建表失败",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
error=str(e),
|
error=str(e),
|
||||||
exc_info=True)
|
exc_info=True)
|
||||||
return False
|
return False
|
||||||
@@ -548,16 +588,16 @@ class MySQLAgent:
|
|||||||
|
|
||||||
if fetch:
|
if fetch:
|
||||||
result = cursor.fetchall()
|
result = cursor.fetchall()
|
||||||
self.log.debug("Query executed", rows=len(result))
|
self.log.debug("查询执行完成", 行数=len(result))
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
affected_rows = cursor.rowcount
|
affected_rows = cursor.rowcount
|
||||||
conn.commit() # 立即提交
|
conn.commit() # 立即提交
|
||||||
self.log.debug("Update executed", affected_rows=affected_rows)
|
self.log.debug("更新执行完成", 受影响行数=affected_rows)
|
||||||
return affected_rows
|
return affected_rows
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error("SQL execution failed",
|
self.log.error("SQL执行失败",
|
||||||
sql=sql,
|
sql=sql,
|
||||||
params=params,
|
params=params,
|
||||||
error=str(e),
|
error=str(e),
|
||||||
@@ -578,9 +618,9 @@ class MySQLAgent:
|
|||||||
try:
|
try:
|
||||||
result = self.execute_sql(sql, params, fetch=True)
|
result = self.execute_sql(sql, params, fetch=True)
|
||||||
exists = result[0][0] > 0 # 适配元组结果
|
exists = result[0][0] > 0 # 适配元组结果
|
||||||
self.log.debug("Checked table existence",
|
self.log.debug("检查表是否存在",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
exists=exists)
|
存在=exists)
|
||||||
return exists
|
return exists
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
@@ -588,16 +628,16 @@ class MySQLAgent:
|
|||||||
def drop_table(self, table_name: str) -> bool:
|
def drop_table(self, table_name: str) -> bool:
|
||||||
"""删除表(原有逻辑完全保留)"""
|
"""删除表(原有逻辑完全保留)"""
|
||||||
if not self.table_exists(table_name):
|
if not self.table_exists(table_name):
|
||||||
self.log.warning("Table does not exist", table=table_name)
|
self.log.warning("表不存在", 表=table_name)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.execute_sql(f"DROP TABLE {table_name}")
|
self.execute_sql(f"DROP TABLE {table_name}")
|
||||||
self.log.info("Table dropped successfully", table=table_name)
|
self.log.info("表删除成功", 表=table_name)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error("Failed to drop table",
|
self.log.error("删除表失败",
|
||||||
table=table_name,
|
表=table_name,
|
||||||
error=str(e),
|
error=str(e),
|
||||||
exc_info=True)
|
exc_info=True)
|
||||||
return False
|
return False
|
||||||
@@ -654,10 +694,10 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# 测试连接
|
# 测试连接
|
||||||
if db.validate_connection():
|
if db.validate_connection():
|
||||||
print("Database connection successful")
|
print("数据库连接成功")
|
||||||
|
|
||||||
# 获取数据库版本
|
# 获取数据库版本
|
||||||
version = db.query_to_df("SELECT VERSION() as version")
|
version = db.query_to_df("SELECT VERSION() as version")
|
||||||
print(f"Database version: {version['version'].iloc[0]}")
|
print(f"数据库版本: {version['version'].iloc[0]}")
|
||||||
else:
|
else:
|
||||||
print("Failed to connect to database")
|
print("连接数据库失败")
|
||||||
|
|||||||
Reference in New Issue
Block a user