discord.py机器人启动时偶发AttributeError: 'Bot'无'db'属性问题
问题原因
你的推测完全正确:Nextcord/Discord.py 的 on_message 事件可能在 on_ready 事件触发之前就开始接收消息。机器人启动流程中,只要与Discord网关建立连接就会开始处理消息,而 on_ready 是在机器人完成所有初始化(如缓存加载、身份验证握手)后才触发的。如果启动过程中有用户发送消息,此时 self.bot.db 还未通过 on_ready 初始化,就会抛出 AttributeError。
修复方案
方案1:临时规避 - 在消息监听中检查数据库状态
修改 leveling.py 中的 on_message 函数,开头先判断数据库连接是否已初始化,未初始化则直接返回:
@commands.Cog.listener() async def on_message(self, message): # 新增:检查db属性是否存在,不存在则跳过处理 if not hasattr(self.bot, 'db'): return if message.author.bot or message.guild is None: return # 后续原有代码保持不变
方案2:彻底解决 - 提前初始化数据库(推荐)
将数据库连接的初始化逻辑从 on_ready 移到机器人启动之前,确保bot启动时 db 属性已经完全就绪。修改 main.py:
import aiosqlite import asyncio from nextcord.ext import commands async def main(): # 初始化bot实例 bot = commands.Bot(command_prefix="!", intents=...) # 先建立数据库连接 bot.db = await aiosqlite.connect('level.db') # 可选:确保表结构存在(避免首次启动时表不存在的错误) async with bot.db.cursor() as cursor: await cursor.execute('''CREATE TABLE IF NOT EXISTS levelSettings (guild INTEGER PRIMARY KEY, levelsys INTEGER)''') await cursor.execute('''CREATE TABLE IF NOT EXISTS levels (user INTEGER, guild INTEGER, level INTEGER, xp INTEGER, PRIMARY KEY(user, guild))''') await bot.db.commit() # 加载cogs await bot.load_extension("cogs.leveling") # 启动机器人 await bot.start("你的机器人令牌") if __name__ == "__main__": asyncio.run(main())
额外优化建议
你的代码中重复执行了多次数据库查询,可以合并查询减少IO开销:
# 替换原有的两次SELECT查询 async with self.bot.db.cursor() as cursor: await cursor.execute('SELECT xp, level FROM levels WHERE user = ? AND guild = ?', (author.id, guild.id)) result = await cursor.fetchone() if result: xp, level = result else: xp, level = 0, 0 await cursor.execute('INSERT INTO levels (level, xp, user, guild) VALUES (?,?,?,?)', (0, 0, author.id, guild.id))
内容的提问来源于stack exchange,提问作者Fawn Nivalen
相关产品推荐
相关产品推荐

