Python+SQLite消息统计机器人出现'int' object is not subscriptable错误
TeleBot消息统计机器人'int' object is not subscriptable错误排查与解决
问题背景
使用Python结合SQLite开发TeleBot消息统计机器人,数据存储正常,但执行/dcount//wcount//mcount统计命令时,触发'int' object is not subscriptable错误,错误指向代码中尝试访问row[1]的行。
错误根源分析
- SQL查询返回值不匹配:
原get_message_count函数的SQL语句为SELECT count(*) FROM messages WHERE group_id=? AND message_date BETWEEN ? AND ? GROUP BY user_id,该查询每一行仅返回单个整数值(消息计数),但代码中尝试访问row[1],而元组只有row[0]一个元素,直接导致下标越界错误。 - 函数参数不匹配:
调用get_message_count时传入了4个参数(chat_id, user_id, start_date, end_date),但函数定义仅接收3个参数,导致参数错位:start_date被赋值为user_id,end_date被赋值为start_date,完全偏离统计逻辑,且查询未过滤目标用户,统计范围错误。 - 变量未初始化:
get_message_count中的output变量未提前初始化,若查询无结果会导致变量未定义;同时循环内直接赋值会覆盖之前的内容,无法累加结果。
解决方法
方案1:统计单个用户的消息数(匹配原handler回复逻辑)
修正get_message_count函数,使其接收正确参数并查询单个用户的消息数:
def get_message_count(chat_id, user_id, start_date, end_date): # 查询指定群、指定用户在时间范围内的消息数 c.execute("SELECT count(*) FROM messages WHERE group_id=? AND user_id=? AND message_date BETWEEN ? AND ?", (chat_id, user_id, start_date, end_date)) result = c.fetchone() # 单个用户用fetchone更高效 return result[0] if result else 0 # 有结果返回计数,无结果返回0
handler中的调用保持不变,回复时直接使用返回的整数值:
# 以/dcount为例 bot.reply_to(message, f"{message.chat.title} - {message.from_user.first_name}: {message_count} 条消息今日。")
方案2:统计群内所有用户的消息数(若需批量统计)
若要统计群内所有用户的消息分布,调整SQL查询返回user_id和计数,并修正结果拼接逻辑:
def get_message_count(chat_id, start_date, end_date): c.execute("SELECT user_id, count(*) FROM messages WHERE group_id=? AND message_date BETWEEN ? AND ? GROUP BY user_id", (chat_id, start_date, end_date)) result = c.fetchall() output = "" for user_id, count in result: output += f"\n用户ID {user_id}: {count} 条消息" return output if output else "暂无消息数据"
同时调整handler的调用,去掉多余的user_id参数:
message_count = get_message_count(chat_id, start_date, end_date)
额外优化点
- 统一日期格式:存入数据库的
message_date保持%Y-%m-%d格式,确保查询时的日期字符串与存储值一致; - 表结构调整:将
message_date的类型从DATETIME改为TEXT(SQLite中DATETIME本质为文本类型,更贴合实际存储); - 变量初始化:所有需要累加的变量提前初始化,避免未定义错误。
内容的提问来源于stack exchange,提问作者VikaS GuttE
相关产品推荐
相关产品推荐

