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

Discord+Sqlite3开发报错:no such table - attendance问题求助

问题排查与解决

你遇到的sqlite3.OperationalError: no such table: attendance错误,核心原因是你只创建了空的attendance.db数据库文件,但没有在其中创建attendance和stats这两张业务需要的表。SQLite只会自动生成数据库文件,但不会帮你创建表结构,必须手动执行建表语句。

解决步骤

  1. 在机器人启动时(on_ready事件中)添加表初始化逻辑,确保必要的表存在:

    • attendance表:存储用户签到状态,字段包括user_id(用户ID,主键)、checked_in(签到状态,0为签退,1为签到)
    • stats表:存储签退统计,字段包括id(主键,固定为1)、num_checked_out(累计签退次数)
  2. 初始化stats表的默认记录:因为你的代码中直接更新id=1的记录,所以需要确保表中有这条初始数据,否则会出现更新失败的问题。

修改后的完整代码

import discord
import sqlite3

client = discord.Client()

@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)
    print('------')
    
    # 初始化数据库表
    conn = sqlite3.connect('attendance.db')
    c = conn.cursor()
    
    # 创建attendance表(如果不存在)
    c.execute('''CREATE TABLE IF NOT EXISTS attendance
                 (user_id INTEGER PRIMARY KEY, checked_in INTEGER DEFAULT 0)''')
    
    # 创建stats表(如果不存在)
    c.execute('''CREATE TABLE IF NOT EXISTS stats
                 (id INTEGER PRIMARY KEY, num_checked_out INTEGER DEFAULT 0)''')
    
    # 检查stats表是否有id=1的记录,没有则插入
    c.execute('SELECT * FROM stats WHERE id = 1')
    if not c.fetchone():
        c.execute('INSERT INTO stats (id, num_checked_out) VALUES (1, 0)')
    
    conn.commit()
    conn.close()

@client.event
async def on_message(message):
    if message.content.startswith('!check-in'):
        conn = sqlite3.connect('attendance.db')
        c = conn.cursor()

        c.execute('SELECT * FROM attendance WHERE user_id = ? AND checked_in = 1', (message.author.id,))
        result = c.fetchone()
        if result:
            await message.channel.send('You are already checked in!')
        else:
            # 使用INSERT OR REPLACE避免用户首次签到时的主键冲突
            c.execute('INSERT OR REPLACE INTO attendance (user_id, checked_in) VALUES (?, 1)', (message.author.id,))
            conn.commit()
            await message.channel.send('You are now checked in!')

        conn.close()

    if message.content.startswith('!check-out'):
        conn = sqlite3.connect('attendance.db')
        c = conn.cursor()

        c.execute('SELECT * FROM attendance WHERE user_id = ? AND checked_in = 1', (message.author.id,))
        result = c.fetchone()
        if result:
            c.execute('UPDATE attendance SET checked_in = 0 WHERE user_id = ?', (message.author.id,))
            c.execute('UPDATE stats SET num_checked_out = num_checked_out + 1 WHERE id = 1')
            conn.commit()
            await message.channel.send('You are now checked out!')
        else:
            await message.channel.send('You are not checked in!')

        conn.close()

    if message.content.startswith('!info'):
        conn = sqlite3.connect('attendance.db')
        c = conn.cursor()

        c.execute('SELECT num_checked_out FROM stats WHERE id = 1')
        num_checked_out = c.fetchone()[0]

        await message.channel.send('{} users have checked out.'.format(num_checked_out))

        conn.close()

# 记得替换成你的机器人Token
client.run('YOUR_DISCORD_BOT_TOKEN')

关键说明

  • CREATE TABLE IF NOT EXISTS:确保只有当表不存在时才执行建表操作,避免重复建表报错。
  • INSERT OR REPLACE:用户首次签到时,如果attendance表中没有该用户记录则插入,已有则更新状态,避免主键冲突错误。
  • stats表初始记录:确保id=1的记录存在,否则UPDATE语句会执行失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:50:21