Discord+Sqlite3开发报错:no such table - attendance问题求助
问题排查与解决
你遇到的sqlite3.OperationalError: no such table: attendance错误,核心原因是你只创建了空的attendance.db数据库文件,但没有在其中创建attendance和stats这两张业务需要的表。SQLite只会自动生成数据库文件,但不会帮你创建表结构,必须手动执行建表语句。
解决步骤
在机器人启动时(
on_ready事件中)添加表初始化逻辑,确保必要的表存在:attendance表:存储用户签到状态,字段包括user_id(用户ID,主键)、checked_in(签到状态,0为签退,1为签到)stats表:存储签退统计,字段包括id(主键,固定为1)、num_checked_out(累计签退次数)
初始化
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
相关产品推荐
相关产品推荐

