Discord.py+PostgreSQL设置服务器自定义前缀报错求助
问题修复方案
1. 搞定「协程create_dp_pool未被等待」警告
说白了就是你调用create_dp_pool的时候没加await,或者在同步代码里直接跑异步函数了。正确的姿势是把数据库连接池的初始化放在异步上下文里:
import asyncpg import discord from discord.ext import commands import asyncio async def create_db_pool(): return await asyncpg.create_pool( user="你的数据库用户名", password="你的数据库密码", database="你的数据库名", host="localhost" ) async def main(): # 先初始化数据库连接池 pool = await create_db_pool() # 定义获取前缀的异步函数 async def get_prefix(bot, message): # 私讯用默认前缀 if not message.guild: return commands.when_mentioned_or("!")(bot, message) # 查数据库里的自定义前缀 record = await pool.fetchrow("SELECT prefix FROM guilds WHERE guild_id = $1", message.guild.id) # 有记录用自定义的,没有用默认! return commands.when_mentioned_or(record["prefix"] if record else "!")(bot, message) # 初始化机器人,记得开全intents(v2.x必须) bot = commands.Bot(command_prefix=get_prefix, intents=discord.Intents.all()) # 把连接池绑到bot上,后面命令里能用 bot.pool = pool # 加载你的命令扩展之类的 # bot.load_extension("cogs.your_cog") await bot.start("你的机器人token") if __name__ == "__main__": asyncio.run(main())
2. 解决「事件循环已在运行」RuntimeError
这个错大多是因为旧教程用的Discord.py v1.x的bot.run(),而v2.x里bot.run()内部会自己创建事件循环,如果你之前手动启动过循环就会冲突。
直接把旧的bot.run()换成上面代码里的asyncio.run(main()),所有异步初始化逻辑(比如连数据库)都塞进main()协程里,让asyncio.run()统一管循环,就不会冲突了。
3. 数据库表得先建好
别忘在PostgreSQL里创建对应的表,不然查不到数据:
CREATE TABLE IF NOT EXISTS guilds ( guild_id BIGINT PRIMARY KEY, prefix TEXT DEFAULT '!' );
4. 版本适配的小提醒
Discord.py v2.x和v1.x差不少:
- 必须显式设置
intents,不然机器人拿不到消息、服务器信息,上面用了Intents.all(),你可以根据需求缩权限。 - 前缀函数支持异步的逻辑没变,但初始化机器人的流程得按v2.x的来。
内容的提问来源于stack exchange,提问作者Old Dude
相关产品推荐
相关产品推荐

