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

Discord机器人等级系统SQLite报错:为何提示‘userid列不存在’?

Discord机器人等级系统报错解决:no such column: userid

错误原因

报错提示找不到userid列,核心问题是创建表的SQL语句完全写错了——你把CREATE TABLE和INSERT INTO捏在了同一条语句里,导致数据库根本没正确创建出带userid、xp、level列的表,后续查询自然找不到对应列。

除此之外还有几个小问题:

  • INSERT时直接写了变量名user,SQL无法识别,得用参数占位符
  • 欢迎消息里的'{user.mention}'格式错误,没法正确@用户
  • on_message里的SELECT语句没传查询参数(?对应的user值)
  • 没过滤机器人自己的消息,会导致bot自己发消息也加XP,陷入循环

解决办法

直接替换成下面修正后的代码,所有问题都已修复:

@client.event
async def on_member_join(member):
    user_id = member.id
    conn = sqlite3.connect('level.db')
    cur = conn.cursor()
    # 先正确创建表,定义列类型(userid设为主键避免重复插入)
    cur.execute('''CREATE TABLE IF NOT EXISTS levels
                   (userid INTEGER PRIMARY KEY, xp INTEGER, level INTEGER)''')
    # 用占位符?传递参数,避免SQL注入,同时确保值正确插入
    cur.execute('INSERT OR IGNORE INTO levels(userid, xp, level) VALUES(?, 0, 0)', (user_id,))
    conn.commit()
    conn.close()
    # 用f-string正确格式化欢迎消息
    await member.send(f"欢迎 {member.mention}!")

@client.event
async def on_message(message):
    # 过滤机器人自己的消息,避免循环
    if message.author.bot:
        return
    # 必须先处理默认的on_message逻辑(如果用的是discord.py v1.x)
    await client.process_commands(message)
    
    user_id = message.author.id
    conn = sqlite3.connect('level.db')
    cur = conn.cursor()
    # SELECT语句要传对应的user_id参数
    cur.execute('SELECT xp, level FROM levels WHERE userid = ?', (user_id,))
    results = cur.fetchone()
    
    # 防止新用户还没进数据库的情况(比如on_member_join没触发时)
    if not results:
        cur.execute('INSERT INTO levels(userid, xp, level) VALUES(?, 1, 0)', (user_id,))
        conn.commit()
        conn.close()
        return
    
    old_xp, old_level = results
    new_xp = old_xp + 1
    new_level = old_level
    
    # 升级逻辑:每级需要的XP用公式计算,示例为(当前等级+1)*25,可自行调整
    required_xp = (old_level + 1) * 25
    if new_xp >= required_xp:
        new_level = old_level + 1
        await message.channel.send(f"恭喜 {message.author.mention} 升级到 {new_level} 级!")
    
    cur.execute('UPDATE levels SET xp = ?, level = ? WHERE userid = ?', (new_xp, new_level, user_id))
    conn.commit()
    conn.close()

关键修改点说明

  1. 拆分创建表语句:单独执行CREATE TABLE,明确列的类型,把userid设为PRIMARY KEY,防止重复插入同一用户的数据
  2. 使用参数占位符:用?代替直接写变量,既安全又能正确传递Python变量到SQL
  3. 过滤bot自身消息:避免bot自己给自己加XP,陷入循环
  4. 完善查询容错:处理用户不在数据库的情况(比如用户没触发on_member_join就发消息)
  5. 优化升级逻辑:用公式计算升级所需XP,扩展性更强,还添加了升级提示消息
  6. 修复字符串格式化:用f-string正确生成欢迎消息和升级提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 12:10:38