You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Telegram Bot异步定时执行MySQL更新任务遇阻求助

解决Telegram机器人定时执行SQL任务的问题

核心方案:使用python-telegram-bot的job_queue

不用再纠结schedule模块的阻塞问题,job_queue是库内置的定时任务工具,和机器人的事件循环深度集成,完全不会影响用户命令的响应。

步骤1:编写定时任务函数

函数必须接受context参数(job_queue会自动传入),在函数内完成数据库更新操作:

import mysql.connector
from telegram.ext import Updater, CommandHandler
from datetime import time

# 替换成你的实际数据库配置
DB_CONFIG = {
    'user': '你的数据库账号',
    'password': '你的数据库密码',
    'host': 'localhost',
    'database': '你的数据库名'
}

def add_daily_rolls(context):
    conn = None
    cursor = None
    try:
        # 建立数据库连接
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()
        # 执行目标SQL语句
        sql = "UPDATE users SET rolls = rolls + 1 WHERE rolls < 12;"
        cursor.execute(sql)
        conn.commit()
        print(f"更新完成,共修改{cursor.rowcount}条记录")
    except mysql.connector.Error as err:
        print(f"数据库错误: {err}")
        if conn:
            conn.rollback()  # 出错时回滚保证数据一致性
    finally:
        # 强制关闭游标和连接,避免资源泄漏
        if cursor:
            cursor.close()
        if conn:
            conn.close()

步骤2:在机器人启动时注册定时任务

在主函数中,通过updater.job_queue添加每日执行的任务,指定你需要的时间点(比如每日8点、14点、20点):

# 你的/rolls命令处理函数(示例,你可替换为自己的实现)
def get_rolls(update, context):
    user_id = update.effective_user.id
    conn = None
    cursor = None
    try:
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()
        cursor.execute("SELECT rolls FROM users WHERE user_id = %s;", (user_id,))
        result = cursor.fetchone()
        if result:
            update.message.reply_text(f"你的rolls数量: {result[0]}")
        else:
            # 首次查询时初始化用户数据
            cursor.execute("INSERT INTO users (user_id, rolls) VALUES (%s, 0);", (user_id,))
            conn.commit()
            update.message.reply_text("已为你初始化rolls,当前数量: 0")
    except mysql.connector.Error as err:
        update.message.reply_text(f"查询失败: {err}")
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

def main():
    # 替换成你的机器人Token
    updater = Updater("你的Telegram机器人Token")
    dp = updater.dispatcher

    # 注册/rolls命令处理器
    dp.add_handler(CommandHandler("rolls", get_rolls))

    # 获取job_queue实例
    job_queue = updater.job_queue

    # 设置每日执行的三个时间点
    daily_times = [
        time(hour=8, minute=0),
        time(hour=14, minute=0),
        time(hour=20, minute=0)
    ]

    # 为每个时间点添加定时任务
    for run_time in daily_times:
        job_queue.run_daily(add_daily_rolls, time=run_time)
        print(f"已添加定时任务:每日{run_time.hour}:{run_time.minute}执行rolls更新")

    # 启动机器人
    updater.start_polling()
    updater.idle()

if __name__ == "__main__":
    main()

关键说明

  • 为什么放弃schedule:schedule的while True循环会阻塞机器人的事件循环,导致无法处理用户的命令请求;而job_queue是基于机器人的事件循环运行的,两者完全兼容。
  • context参数:job_queue会自动给定时任务函数传入这个参数,即使你在函数里不用它,也必须保留这个参数,否则会报错。
  • 数据库连接:每次任务执行时新建连接、执行后关闭,避免长时间持有连接导致失效;如果需要更高性能,可以考虑使用数据库连接池。

内容的提问来源于stack exchange,提问作者user19976230

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:43:32