一:无法获取表信息
处理流程分析
初始问题:get_room_member_list 函数调用后,未能收到预期的群成员列表回调
Error: not all arguments converted during string formatting
127.0.0.1 - - [26/Feb/2025 11:55:32] "POST / HTTP/1.1" 500 -
# 错误代码
def insert_group_from_room_list(self, room_list):
# ... (省略部分代码) ...
cursor = self._execute_query(sql, group_data_list) # <--- 使用 cursor.executemany 批量插入
# ...
调用 get_room_member_list 函数(该函数用于获取数据库表中的信息)后,Flask 应用没有接收到 WW_DATA_MEMBER_LIST_MSG 类型的回调消息,或者收到了但没有正确处理
def insert_group_from_room_list(self, room_list):
# ... (省略部分代码) ...
cursor = self.connection.cursor()
inserted_count = 0
try:
for group_data_tuple in group_data_list: # 循环处理 group_data_list
cursor.execute(sql, group_data_tuple) # <--- 使用 cursor.execute 执行单条插入
inserted_count += 1
self.connection.commit() # 循环结束后提交事务
# ...
请求发送格式错误 (MessageBuilder 配置不当导致)
开始通过程序代运行无法判断是否为服务器问题,通过调试工具发现,发送到 8888 端口服务器的请求格式不正确,导致服务器无法识别请求,因此没有发送回调
错误根源:MessageBuilder 类中 type_specific 字典对于 WW_DATA_MEMBER_LIST_MSG 等群组管理消息类型的定义不正确,错误地包含了 conversation_id 在 required_fields 中,导致构建的 payload 格式与服务器期望的不符
修改 MessageBuilder 类中 type_specific 字典的定义,移除 WW_DATA_MEMBER_LIST_MSG 等消息类型定义中多余的 conversation_id 字段,确保 payload 结构符合 8888 端口服务器的要求
修改插入数据字段后,代码的问题仍然没有修复
Flask 应用缺少 WW_DATA_MEMBER_LIST_MSG 回调处理逻辑
问题主要表现在即使请求发送格式正确后,Flask 应用仍然无法处理群成员列表回调
查询代码后发现原因在于 handle_request 函数中缺少处理 WW_DATA_MEMBER_LIST_MSG 类型回调消息的代码分支 (elif msg['type'] == 'WW_DATA_MEMBER_LIST_MSG':),简单来说就是没有处理该请求
在 handle_request 函数中添加 elif msg['type'] == 'WW_DATA_MEMBER_LIST_MSG': 代码块,用于处理 WW_DATA_MEMBER_LIST_MSG 类型的回调消息,并封装到独立的 handle_room_member_list_callback 函数中;但是增加后还是没有解决问题
MySQL 数据库主键冲突错误 (Duplicate entry ... for key 'groups.PRIMARY'
问题的主要表现:在处理群组列表回调 (WW_DATA_ROOM_LIST_MSG) 时,出现 MySQL 数据库主键冲突错误,无法插入新的群组信息
根本原因分析:insert_group_from_room_list 函数使用了简单的 INSERT 语句,没有处理 conversation_id 重复的情况。 当多次收到包含相同群组信息的 WW_DATA_ROOM_LIST_MSG 回调时,尝试重复插入已存在的群组,导致主键冲突
修改 insert_group_from_room_list 函数,使用 INSERT ... ON DUPLICATE KEY UPDATE SQL 语句,实现当 conversation_id 冲突时更新现有记录,而不是插入失败。 同时,也对 insert_user 和 insert_group_member 方法进行了类似的修改,以统一处理重复记录的逻辑
但是插入多个数据的时候错误仍然存在
TypeError: not all arguments converted during string formatting 错误 (批量插入参数数量不匹配)
[2025-02-26 13:22:00,218] ERROR in app: Exception on / [POST]
Traceback (most recent call last):
File "E:\Anaconda3\Lib\site-packages\flask\app.py", line 2529, in wsgi_app
response = self.full_dispatch_request()
File "E:\Anaconda3\Lib\site-packages\flask\app.py", line 1826, in full_dispatch_request
return self.finalize_request(rv)
File "E:\Anaconda3\Lib\site-packages\flask\app.py", line 1845, in finalize_request
response = self.make_response(rv)
File "E:\Anaconda3\Lib\site-packages\flask\app.py", line 2138, in make_response
raise TypeError(
TypeError: The view function for 'handle_request' did not return a valid response. The function either returned None or ended without a return statement.
127.0.0.1 - - [26/Feb/2025 13:22:00] "POST / HTTP/1.1" 500 -
在使用了 ON DUPLICATE KEY UPDATE 的 insert_group_from_room_list 函数后,出现 TypeError: not all arguments converted during string formatting 错误
批量插入不成功大概率是插入的格式出现了问题。cursor.executemany 批量插入方法与 ON DUPLICATE KEY UPDATE 语句的结合使用可能存在兼容性问题,导致参数格式化错误。 此外,错误地为 group_data_tuple 元组添加了 5 个元素,与 SQL 语句 VALUES 子句的 3 个占位符数量不符
针对该问题主要实践
-
将 insert_group_from_room_list 函数的批量插入方式 (cursor.executemany) 修改为循环单条插入方式 (cursor.execute),避免 cursor.executemany 与 ON DUPLICATE KEY UPDATE 的潜在冲突
-
修正 group_data_tuple 的创建方式,确保每个元组只包含 3 个参数,与 SQL 语句 VALUES 子句的占位符数量匹配
结果:此时群组的数据已经可以添加成功
# 错误代码
elif msg['type'] == 'WW_DATA_ROOM_LIST_MSG':
# ...
if room_list_data:
# ...
try:
# ...
print("成功存储群组列表信息到数据库。")
except pymysql.Error as db_err:
# ...
return jsonify({"status": "failed", "message": "数据库操作失败"}), 500
# finally:
# db.close_connection()
# return jsonify({"status": "processed", "message": "群组列表已处理"}) # <--- 这里被注释掉了
# ...
# 修改后的代码
elif msg['type'] == 'WW_DATA_ROOM_LIST_MSG':
# 进入该逻辑
# ...
if room_list_data:
# db.connect()
try:
# ...
print("成功存储群组列表信息到数据库。")
except pymysql.Error as db_err:
# ...
return jsonify({"status": "failed", "message": "数据库操作失败"}), 500
# finally:
# db.close_connection()
return jsonify({"status": "processed", "message": "群组列表已处理"}) # <--- 取消注释这行
# ...
Flask 视图函数未返回有效响应 (TypeError: The view function ... did not return a valid response)
数组中的数据成功插入后,Flask 应用抛出 TypeError,提示 handle_request 函数没有返回有效的响应。该处是一个小错误,主要原因是因为函数处理完成后并没有及时的返回的响应
错误反思总结
解决问题思路总结
首先就是仔细阅读错误信息,根据错误信息的提示,去判断该错误的根源在哪里;然后在代码中查看日志信息,在主要流程以及关键变量部分, 从而定位到错误发生的具体位置。例如在处理数据库错误的时候,添加SQL查询语句日志以及参数日志,这些日志信息都是进一步诊断出错误关键
然后是逐步排查,一般排查的思路是逐步深入,从最外层开始,逐步到代码内部,逐步排查出来问题,例如上述在解决数据没有响应的时候,先排查回调处理逻辑,然后深入到请求构建逻辑,最后到数据库的操作逻辑
排查过程中结合调试工具进一步对可能出现的错误,以及会出现错误的地方进行验证。通过APIfox模拟发送请求,检查接口是否健康可用,同时还通过数据库可视化工具,实时监控数据库的变化,从而实时判断出自己解决问题的思路是否正确
遇到一些自己不理解的问题,善用AI工具,对一些细节或者模糊不清的逻辑知识进行梳理。与此同时借用AI工具健壮自身的的代码,提供更多的异常检测
二:批量插入数据错误
处理流程分析
pymysql 库在批量执行更新语句的时候出现不兼容的情况
代码中批量执行INSERT ... ON DUPLICATE KEY UPDATE 语句时,可能存在某种不兼容性或行为差异,导致 "Error: not enough arguments for format string" 错误。从代码层面看,SQL 语句和参数列表都准备得似乎没有问题, 但在 pymysql 库的深层处理中, 批量 executemany 与 ON DUPLICATE KEY UPDATE 的组合可能触发了字符串格式化引擎的错误, 报出了一个 误导性的 "参数不足" 错误
此处出现的参数不足问题,检查后发现并不是真正因为参数的数量不够,而是pymysql或者mysql在这种批量处理的时候,内部参数的处理机制可能和我们的预期是不符合的,从而最终导致了格式化过程的异常。出现该错误的时候,对自身的修改路线本身产生了很大的误导性,一开始以为是代码参数传递错误,但是忽略了SQL都语句本身复杂性所带来的问题
解决问题思路总结
首先, 我从 单条数据插入 开始验证, 确认最基本的数据库连接、 SQL INSERT 语句、 和参数传递都是没有问题的。 单条插入成功, 说明数据库层面基本功能是正常的
然后在此基础上逐步增加难度,然后开始执行批量插入,看看是否是调用量插入本身的问题。然后简化SQL语句,在插入的时候移除了ONDUPLICATE KEY UPDATE,然后再执行批量插入,然后插入成功,最终也证明了该处就是问题的根源。
处理错误过程中,在重要的位置都加上了详细的日志,主要是每一次看到数据库的反应,以及数据库语句的执行情况,这样可以帮助深入到代码的内部,观察数据流和程序的执行状态,从而定位问题
期间为了排除都是因为flask框架所导致的问题,专门建立了一个测试函数,专门测试数据的插入是否正确,从而进一步的缩小问题的范围
错误反思总结
针对于上述出现错误,对以后自己的提示
- 每次使用SQL语句和占位符的事后,一定要清楚SQL语句中%s占位符的数量,需要和提供的参数元组中的元素数量一致
-
简化 SQL 语句, 逐步增加复杂度: 如果 SQL 语句比较复杂 (例如包含 ON DUPLICATE KEY UPDATE、 多表连接等), 先简化 SQL 语句到最基本的 INSERT ... VALUES 形式, 验证基本插入功能是否正常。 如果基本插入没问题, 再逐步增加 SQL 语句的复杂度, 每次增加一点, 就测试一下, 看看在哪一步开始出现错误。不要尝试一步到位的数据库书写方法
-
遇到棘手的问题,单独外部进行测试,这样测试环境不受到其他影响,也可以更好的排除