Discord.py 如何在 运行 bot 启动时初始化数据库连接

Discord.py How to initialize database connection when running bot startup

所以我有一个“link”命令,它基本上将用户和一些其他数据添加到 MongoDB 云数据库。现在,命令非常慢,因为每次调用命令时,我们都会通过连接 url.

重新连接到数据库

我想到了在 main.py 文件中使用 Singleton 模式来初始化数据库 class ,这样无论何时我需要以任何方式更新数据库,连接都已经建立.但是,我了解到这种模式通常不受欢迎,那么有没有更好的方法呢?

main.py

import os

from utils import loadConfig
from discord.ext import commands

config = loadConfig.load("config.json")

bot = commands.Bot(
    command_prefix=config["prefix"]
)

for file in os.listdir("cogs"):
    if file.endswith(".py"):
        name = file[:-3]
        bot.load_extension(f"cogs.{name}")

bot.run(config["token"])

commands.py

import discord

from utils import loadConfig, processDB
from discord.ext import commands


class command(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.config = loadConfig.load("config.json")

    @commands.command()
    async def link(self, ctx, username):
        """ Links a user's profile """
        if processDB.processUsername(ctx.author.id, username):
            await ctx.send("Done!")
        else:
            await ctx.send("Oops, something went wrong")

def setup(bot):
    bot.add_cog(command(bot))

processDB.py

from pymongo import MongoClient

import utils.processApi as processApi

CONNECTION_URL = ""

cluster = MongoClient(CONNECTION_URL)
db = cluster["discordBotData"]
userDataCollection = db["userData"]

#do stuff...

您可以选择通过 cog 加载传递数据库客户端对象。本质上,如果您创建一个 class 来模拟您的 discord bot 客户端,您可以添加一个自定义方法来获取存储的数据库客户端对象。

class Client(commands.Bot):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.cluster = MongoClient(CONNECTION_URL)

        for file in os.listdir("cogs"):
            if file.endswith(".py"):
                name = file[:-3]
                self.load_extension(f"cogs.{name}")

    def get_cluster(self):
        return self.cluster

然后您需要修改从 cogs 加载的数据库集群,以便直接从客户端收集数据。

class command(commands.Cog):
    def __init__(self, client):
        self.client = client
        self.cluster = self.client.get_cluster()