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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:50:21