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()