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

Time:05-13

So I have a "link" command that essentially adds a user and some other data to a MongoDB Cloud database. Right now, the command is very slow as each time the command is called, we reconnect to the DB via a connection url.

I thought of using the Singleton pattern to initialize the Database class in the main.py file, so that whenever I need to update the database in any way, a connection will already have been established. However, I read that this pattern is generally discouraged, so is there a better way of doing this?

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...

CodePudding user response:

You have the option of passing the database client object through your cog loading. Essentially if you create a class that models your discord bot client, you can add a custom method to fetch the stored database client object.

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

Then you will need to make modifications to the loading of your database cluster from your cogs to gather directly from the client.

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