AttributeError: 'Bot' object has no attribute 'db'

1.3k Views Asked by At

I a bot using discord.py and using aiosqlite for a leveling database. Sometimes when I start up my bot, I get this error, and Im not sure what is causing it. It doesn't happen every time I start my bot. I think it happens when my bot is in the middle of starting up and someone sends a message in the server? Im not sure.

Ignoring exception in on_message
Traceback (most recent call last):
  File "C:\Users\kouxi\AppData\Local\Programs\Python\Python310\lib\site-packages\nextcord\client.py", line 502, in _run_event
    await coro(*args, **kwargs)
  File "c:\Users\kouxi\Runa\cogs\leveling.py", line 27, in on_message
    async with self.bot.db.cursor() as cursor:
AttributeError: 'Bot' object has no attribute 'db'

This is the error

  #add xp on message and checking for leveling up
  @commands.Cog.listener()
  async def on_message(self, message):
    if message.author.bot or message.guild is None:
      return
    author=message.author
    guild=message.guild
    async with self.bot.db.cursor() as cursor:
      await cursor.execute('SELECT levelsys FROM levelSettings WHERE guild = ?',(guild.id,))
      levelsys=await cursor.fetchone()
      if levelsys and not levelsys[0]:
        return
      await cursor.execute('SELECT xp FROM levels WHERE user = ? AND guild = ?',(author.id,guild.id))
      xp=await cursor.fetchone()
      await cursor.execute('SELECT level FROM levels WHERE user = ? AND guild = ?',(author.id,guild.id))
      level=await cursor.fetchone()
      if not xp or not level:
        await cursor.execute('INSERT INTO levels (level, xp, user, guild) VALUES (?,?,?,?)',(0,0, author.id, guild.id))
      try:
        xp=xp[0]
        level=level[0]
      except TypeError:
        xp=0
        level=0
      if level < 5:
        xp+=random.randint(1,3)
        await cursor.execute('UPDATE levels SET xp = ? WHERE user = ? AND guild = ?',(xp,author.id,guild.id))
      else:
        rand=random.randint(1,(level//4))
        if rand==1:
          xp+=random.randint(1,3)
          await cursor.execute('UPDATE levels SET xp = ? WHERE user = ? AND guild = ?',(xp,author.id,guild.id))
      if xp >= 100:
        level +=1
        await cursor.execute("UPDATE levels SET level = ? WHERE user = ? AND guild = ?",(level,author.id,guild.id))
        await cursor.execute("UPDATE levels SET xp = ? WHERE user = ? AND guild = ?",(0,author.id,guild.id))
        await message.channel.send(f'{author.name} has leveled up to level {level}!')
    await self.bot.db.commit()

This is the block of code, in my Cogs under leveling.py. I have bot.db=await aiosqlite.connect('level.db') in my main.py file under on_ready(). Thank you!

1

There are 1 best solutions below

0
moinierer3000 On

As said in the comment, you should use setup_hook if you want to setup something before the bot starts.
You will need to subclass your bot though:

# First you need to subclass your bot
class MyBot(commands.Bot):
    # Use the init function to attach a variable to your bot
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.db = None

    # And then define your setup_hook function
    async def setup_hook(self):
        if not self.db:
            print("Setting up db..")
            self.db = await aiosqlite.connect("level.db")


# And then you can use the class as a replacement for commands.Bot
bot = MyBot(command_prefix=..., intents=...)