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

aiogram开发Bot出现SQLite数据未持久化及战斗函数异常求助

问题排查与解决方案

一、战斗函数无法运行的问题

你的fight函数存在多个语法与逻辑错误,逐一修正如下:

  1. SQL语法错误
    UPDATE语句中用==赋值是错误的,SQL标准赋值符号为=;同时WHERE子句中user_id = 'user_id '是硬编码字符串,没有使用传入的user_id变量,多余空格还会导致数据匹配失败。

  2. 变量覆盖与逻辑错误
    你直接覆盖了从profile查询到的damage变量,导致更新回数据库的是战斗计算后的伤害值而非原角色伤害,完全不符合战斗逻辑,应使用临时变量存储计算出的伤害。

  3. 嵌套循环冗余
    一个用户对应一条profile数据和一条mob数据,嵌套循环会导致重复执行更新操作,完全没必要,应分别查询单条数据处理。

  4. SQL注入风险
    用f-string拼接SQL语句存在注入风险,且容易出现变量替换错误,必须使用参数化查询。

修正后的战斗函数代码

def fight(user_id: int):
    # 查询用户角色数据
    profile_cursor = sql.execute("SELECT hp, damage, power, armor FROM profile WHERE user_id = ?", (user_id,))
    profile_data = profile_cursor.fetchone()
    if not profile_data:
        print("用户角色数据不存在")
        return
    
    hp, user_damage, user_power, user_armor = profile_data
    
    # 查询怪物数据
    mob_cursor = sql.execute("SELECT mob_id, hp_mob, damage_mob, power_mob, armor_mob FROM mob WHERE user_id = ?", (user_id,))
    mob_data = mob_cursor.fetchone()
    if not mob_data:
        print("怪物数据不存在")
        return
    
    mob_id, mob_hp, mob_damage, mob_power, mob_armor = mob_data
    
    # 计算伤害(用临时变量存储,不覆盖原数据,同时避免负数伤害)
    player_take_damage = max(0, mob_power - user_armor)
    mob_take_damage = max(0, user_power - mob_armor)
    
    # 更新角色血量
    new_hp = hp - player_take_damage
    sql.execute("UPDATE profile SET hp = ? WHERE user_id = ?", (new_hp, user_id))
    
    # 更新怪物血量
    new_mob_hp = mob_hp - mob_take_damage
    sql.execute("UPDATE mob SET hp_mob = ? WHERE user_id = ?", (new_mob_hp, user_id))
    
    # 统一提交事务(无需每次更新都commit,一次提交更高效)
    db.commit()
    
    print(f"玩家受到伤害: {player_take_damage}")
    print(f"怪物受到伤害: {mob_take_damage}")

二、SQLite数据偶尔无法保存的问题

结合aiogram异步框架特性,问题根源通常在以下几点:

  1. 线程安全问题
    SQLite默认不允许跨线程使用同一个连接,aiogram的异步任务可能运行在不同线程中,导致连接冲突。解决方法:

    • 创建连接时添加check_same_thread=False参数:
      import sqlite3
      db = sqlite3.connect("your_db.db", check_same_thread=False)
      
    • 更推荐使用aiosqlite这类异步SQL库,适配aiogram的异步环境。
  2. 事务提交与异常处理
    若代码中存在未捕获的异常,会导致事务无法正常提交甚至回滚。需添加异常捕获与回滚逻辑:

    try:
        # 执行SQL操作
        sql.execute(...)
        db.commit()
    except Exception as e:
        db.rollback()
        print(f"数据库操作失败: {e}")
    
  3. 连接复用问题
    避免频繁创建和关闭数据库连接,建议全局复用同一个连接实例;若必须使用多连接,需确保每个连接独立提交事务。

  4. 异步阻塞问题
    同步SQLite操作会阻塞aiogram的异步事件循环,导致任务堆积,间接引发数据保存异常。改用aiosqlite实现异步数据库操作:

    import aiosqlite
    
    async def fight(user_id: int):
        async with aiosqlite.connect("your_db.db") as db:
            async with db.execute("SELECT hp, damage, power, armor FROM profile WHERE user_id = ?", (user_id,)) as cursor:
                profile_data = await cursor.fetchone()
            # 后续所有数据库操作前加await
            await db.execute("UPDATE profile SET hp = ? WHERE user_id = ?", (new_hp, user_id))
            await db.commit()
    

内容的提问来源于stack exchange,提问作者Матвей Васильев

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:45:45