My aiosqlite Python database wont update the second table when I try - python

I have a aiosqlite Python database for a discord bot using Nextcord.
I have one table that works fine but the second one just wont update or maybe even create (I'm not sure). I'm wondering if it being in a class for a Nextcord cog is something to do with the issue.
I tried almost everything I could think of even using chatGPT. I Have no idea why its like this and don't use SQL DS's enough to know why. I have been trying to fix this for over 3 months so any help would be appreciated.
The code is here:
async def create_tables(self):
if self.db is not None:
await self.db.execute('CREATE TABLE IF NOT EXISTS econ (spin_tokens INTEGER, tokens INTEGER, slash_cmds INTEGER, status INTEGER, dank INTEGER, user INTEGER)')
await self.db.execute('CREATE TABLE IF NOT EXISTS daily (daily_claim INTEGER, daily_claimed_stamp INTEGER, daily_streak INTEGER, user INTEGER)')
async def commit(self):
await self.connect.commit()
#commands.Cog.listener()
async def on_ready(self):
self.bot.db = await aiosqlite.connect("econ.db")
await asyncio.sleep(3)
await self.create_tables()
await self.bot.db.commit()
print("DB ready...")
print("-----------")`
async def get_dval(self, user):
async with self.bot.db.cursor() as cursor:
await cursor.execute("SELECT daily_claim, daily_claimed_stamp, daily_streak FROM daily WHERE user = ?", (user.id,))
data = await cursor.fetchone()
print(data)
if data is None:
await self.daily_make(user)
return 0, 0, 1, 0
(daily_claim, daily_claimed_stamp, daily_streak) = data[0], data[1], data[2]
return daily_claim, daily_claimed_stamp, daily_streak
async def dclaimed_update(self, user, mode="daily_claim"):
now = datetime.now()
now_time = now.strftime("%H.%M")
print(now_time)
if self.db is not None:
await self.db.execute(f'''UPDATE daily SET daily_claim = now_time WHERE user = (user.id)''')
await self.db.commit()
#nextcord.slash_command(description="adds to bal")
async def daily(self, interaction : Interaction):
now = datetime.now()
now_time = now.strftime("%H.%M")
print(now_time)
daily_claim, daily_claimed_stamp, daily_streak = await self.get_dval(interaction.user)
if daily_claim == 0:
resK = await self.dclaimed_update(interaction.user)
daily_claim, daily_claimed_stamp, daily_streak = await self.get_dval(interaction.user)
await interaction.send("Sugg")
else:
await interaction.send("No")

Related

aiosqlite "Result" object has no attribue "execute"

I'm making a discord.py bot and I'm currently on the economy part, but I'm encountering a strange error that I've never ran into before and has most of the python discord help dumbfounded. The error is as follows:
Command raised an exception: AttributeError: 'Result' has no attribute 'execute'
I'm having trouble understanding the meaning of this error due to the fact that I'm executing it on a cursor object, and not a result?
For those who need the code, here you go:
# Imports
import discord
from discord.ext import commands
from random import randrange
import asyncio
import time
import aiosqlite
# Def balance funcs
def getBal(ctx, user : discord.Member):
main = aiosqlite.connect('main.db')
cursor = main.cursor()
cursor.execute(f"SELECT balance FROM MainTable WHERE member_id = {user.id} AND guild_id = {ctx.guild.id}")
result = cursor.fetchone()
if result:
return
if not result:
sql = "INSERT INTO MainTable(balance, guild_id, member_id, warns) VALUES(?,?,?,?)"
val = (0, ctx.guild.id, user.id, 0)
cursor.execute(sql, val)
main.commit()
cursor.close()
main.close()
# Def main class
class Balance(commands.Cog):
#commands.command(aliases=['bal'])
async def balance(self, ctx, user : discord.Member = None):
if user == None:
user = ctx.author
getBal(ctx, user)
else:
getBal(ctx, user)
main = aiosqlite.connect('main.db')
cursor = main.cursor()
cursor.execute(f"SELECT balance FROM MainTable WHERE member_id = {user.id} AND guild_id = {ctx.guild.id}")
result = cursor.fetchone()
if result is not None:
if user is None:
embed = discord.Embed(title=f"**{ctx.author.mention}'s Balance**", description=f"**{ctx.author.mention}** has **{result[0]}** coins.", color=0xffffff)
await ctx.send(embed=embed)
else:
embed = discord.Embed(title=f"**{user.mention}'s Balance**", description=f"**{user.mention}** has **{result[0]}** coins.", color=0xffffff)
await ctx.send(embed=embed)
else:
await ctx.send("Critical Error! Please contact the developers.")
# Initialize
def setup(bot):
bot.add_cog(Balance(bot))
print('Balance is loaded')
You should read documentation for aiosqlite because it works different then standard sqlite3
You need
cursor = await main.execute(...)
EDIT:
It may also need to use await in every function. And add async before def
async def get_balance(ctx, user : discord.Member): # PEP8: readable names
main = await aiosqlite.connect('main.db')
cursor = await main.execute(f"SELECT balance FROM MainTable WHERE member_id = {user.id} AND guild_id = {ctx.guild.id}")
result = await cursor.fetchone()
if result:
return
# there is no need to check `not result`
sql = "INSERT INTO MainTable(balance, guild_id, member_id, warns) VALUES(?,?,?,?)"
val = (0, ctx.guild.id, user.id, 0)
cursor = await main.execute(sql, val)
await main.commit()
await cursor.close()
await main.close()
and later you have to run it also with await
await get_balance(ctx, user)
PEP 8 -- Style Guide for Python Code

Nothing happens with this command and don't know why. Everything looks fine

class EconomyCog(commands.Cog, name="Help"):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def Money(self, ctx, member:discord.Member):
member = ctx.author
member_id = ctx.author.id
db = sqlite3.connect("main.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT member_id FROM main WHERE member_id = {member_id}")
result = cursor.fetchone()
if result is None:
sql = (f"INSERT INTO main(member_id, money) VALUES(?, ?)")
val = (member_id, 500)
cursor.execute(sql, val)
db.commit
await ctx.send("Because you didn't have an account, I just made one for you!")
db.close
cursor.close
elif result is not None:
db = sqlite3.connect("main.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT * FROM main WHERE member_id = {member_id}")
result = cursor.fetchone()
embed = discord.Embed(title = f"{member}'s Money", description = f"{result[1]} <:BitCoin:929595745500274689>", color = discord.Colour.random)
await ctx.send(embed=embed)
I don't get any errors but also when the command is triggered nothing happens. You have any clue to why it won't work?
These lines do nothing. They don't call functions, they just mention the function objects:
db.commit
...
db.close
cursor.close
It's exactly like writing:
7
It is syntactically legal, but does nothing.
To call them, you MUST use parens. Also note that you don't need to refetch the member record in the else; you can have that first query serve both purposes:
async def Money(self, ctx, member:discord.Member):
member = ctx.author
member_id = ctx.author.id
db = sqlite3.connect("main.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT * FROM main WHERE member_id = ?", (member_id,))
result = cursor.fetchone()
if result is None:
sql = (f"INSERT INTO main(member_id, money) VALUES(?, ?)")
val = (member_id, 500)
cursor.execute(sql, val)
db.commit()
await ctx.send("Because you didn't have an account, I just made one for you!")
else:
embed = discord.Embed(title = f"{member}'s Money", description = f"{result[1]} <:BitCoin:929595745500274689>", color = discord.Colour.random)
await ctx.send(embed=embed)
cursor.close()
db.close()

How to use discord.PartialEmoji/discord.Emoji object?

I need to get an emoji as an emoji object for reaction roles but i whatever i do i ether get the error
discord.ext.commands.errors.PartialEmojiConversionFailure: Couldn't convert " " to PartialEmoji.
if i am using discord.PartialEmoji or
discord.ext.commands.errors.EmojiNotFound: Emoji " " not found.
if i am using discord.Eomji.
Example Code where these errors happen
#commands.command()
async def test(self,ctx,emoji: discord.Emoji = None):
await ctx.send(emoji)
Edit:
At first the reaction role should be created like this:
#commands.command()
async def reactionrole(self,ctx,msgid: int = None,emoji: discord.Emoji = None , role: discord.Role = None ):
if msgid is None:
await ctx.send('Use the following template to create reactionroles (ex. treactionrole <#messageid> <emoji> <#role>)')
elif emoji is None:
await ctx.send('Use the following template to create reactionroles (ex. treactionrole <#messageid> <emoji> <#role>)')
elif role is None:
await ctx.send('Use the following template to create reactionroles (ex. treactionrole <#messageid> <emoji> <#role>)')
else:
if ctx.message.author.guild_permissions.manage_roles:
db = sqlite3.connect("db.sqlite")
cursor = db.cursor()
sql = ("INSERT INTO reaction_role(message_id,emoji,role) VALUES(?,?,?)")
val = (msgid,emoji,str(role))
msg = await ctx.channel.fetch_message(int(msgid))
await msg.add_reaction(emoji)
cursor.execute(sql,val)
db.commit()
cursor.close()
db.close()
else:
await ctx.author.send('You dont have the permission to use reactionroles on this Server!')
Then if an reaction happens an method should get the message out of the db where the msgid and the emoji is the same as the reacted one like this:
async def reaction_roles_role(msgid,emoji):
db = sqlite3.connect("db.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT role FROM reaction_role WHERE message_id = {msgid} and emoji = {emoji}")
result = cursor.fetchone()
return result
Are you using default emojis for this or Emojis from other servers? Because discord.Emoji only works with custom Emojis from servers with your bot on it.
If you wanna get all of these you have to do something like this:
#commands.command()
async def test(self, ctx, emoji):
print(str(emoji))
And for reaction roles you could compare in on_raw_reaction_add like this:
if str(payload.emoji) == str(your_emoji_here):

How to integrate on_message with sqlite3 in discord.py?

I made an on_message event that gives you role whenever you mention 3 people in a specific channel , Now I am trying to integrate it with database so it can be used on multiple guilds.
What I've write:
class ScrimsCog(commands.Cog, name='Scrims-Commands') :
def __init__(self,bot):
self.bot = bot
#commands.Cog.listener()
async def on_message(self,message):
db = sqlite3.connect('main.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT channel_id FROM main WHERE guild_id = {message.guild.id}")
result = cursor.fetchone()
if result is None:
return
else:
cursor.execute(f"SELECT role FROM main WHERE guild_id = {message.guild.id}")
if not channel.id == channel_id:
return
if len(message.mentions) >= 3:
await message.add_reaction(emoji="<a:tick:748476262640779276>")
role = discord.utils.get(message.guild.roles, name=role)
user = message.author
await user.add_roles(role)
await self.bot.process_commands(message)
#commands.group(invoke_without_command=True)
async def scrimsmod(self,ctx):
await ctx.send('Available Setup Commands: \nscrimsmod channel <#channel>\nscrimsmod role <message>')
#scrimsmod.command()
async def channel(self, ctx, channel:discord.TextChannel):
if ctx.message.author.guild_permissions.manage_messages:
db = sqlite3.connect('main.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT channel_id FROM main WHERE guild_id = {ctx.guild.id}")
result = cursor.fetchone()
if result is None:
sql = ("INSERT INTO main(guild_id, channel_id) VALUES(?,?)")
val = (ctx.guild.id, channel.id)
await ctx.send(f" Default Registration Channel has been set to {channel.mention}")
elif result is not None:
sql = ("UPDATE main SET channel_id = ? WHERE guild_id = ?")
val = (channel.id, ctx.guild.id)
await ctx.send(f"Default Registration Channel has been updated to {channel.mention}")
cursor.execute(sql, val)
db.commit()
cursor.close()
db.close()
#scrimsmod.command()
async def role(self, ctx,role: discord.Role):
if ctx.message.author.guild_permissions.manage_messages:
db = sqlite3.connect('main.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT role FROM main WHERE guild_id = {ctx.guild.id}")
result = cursor.fetchone()
if result is None:
sql = ("INSERT INTO main(guild_id, role) VALUES(?,?)")
val = (ctx.guild.id, role)
await ctx.send(f"Default role to give on correct registration have been set to `{role}`")
elif result is not None:
sql = ("UPDATE main SET role = ? WHERE guild_id = ?")
val = (role, ctx.guild.id)
await ctx.send(f"Default role to give on correct registration have been updated to `{role}`")
cursor.execute(sql, val)
db.commit()
cursor.close()
db.close()
def setup(bot):
bot.add_cog(ScrimsCog(bot))
print("Scrims cog is loaded!")
From now I think the problem is with on_message part, the channel.id , channel-id, role are undefined but even if I define them it still doesn't work.
f-string maybe causing problems, try this..
cursor.execute("SELECT channel_id FROM main WHERE guild_id = ?", [message.guild.id])
At first, if you connect to the database under the on_message event, this this reduces the efficiency of your bot. And for the other problems, you have to change the commands parameters like these
async def channel(self, ctx, channel):, async def role(self, ctx,role):
instead of these role: discord.Role channel: discord.TextChannel.
Then, when you want to call the channel or the role, you must use discord.utils.get,
for channels:
await ctx.send(f"Default Registration Channel has been updated to {discord.utils.get(ctx.guild.text_channels, name=channel).mention}")
for roles:
await ctx.send(f"Default role to give on correct registration have been updated to {discord.utils.get(ctx.guild.roles, name=role)}")
So when the users using the role or channel commands, they must write the exact channel.
And when you comparing the channel id with the database, you can also use discord.utils.get like this:
channel_in_database = discord.utils.get(ctx.guild.text_channels, name="in here, you need to connect to the database and take the channel name for this guild.")
then, if not channel_in_database.id == ctx.channel.id:, or maybe you can(I'm not 100% sure that will work) take the channel name from database for that guild and do:
if "channel name from the database" == ctx.channel.name
If one of these raises any problem or if you still have unanswered problems, just comment

Missing 1 required positional argument: 'number'

Hi I'm having an issue running a asyncio loop it's asking for a missing 1 required positional argument: 'number'.
Here is what I'm working with:
async def purge_modlog(ctx, number):
tomorrow = datetime.now()+timedelta(days=1)
midnight = datetime(year=tomorrow.year, month=tomorrow.month,
day=tomorrow.day, hour=20, minute=35, second=0)
number = int(number)
server = before.server
db = fileIO(self.direct, "load")
if not server.id in db:
return
channel = db[server.id]["Channel"]
if number > 99 or number < 1:
await ctx.send("I can only delete messages within a range of 1 - 99", delete_after=10)
else:
author = ctx.message.author
authorID = author.id
mgs = []
number = int(number)
channel = modlog
async for x in bot.logs_from((channel), limit = int(number+1)):
mgs.append(x)
await asyncio.sleep((midnight - datetime.now()).seconds)
print("Deleting modlog messages 14 day or older")
await asyncio.sleep(5)
await delete_messages(mgs)
await ctx.send('Success!', delete_after=4)
await asyncio.sleep(86400) # Wait 24 hours
def check_folder():
if not os.path.exists('data/modlogset'):
print('Creating data/modlogset folder...')
os.makedirs('data/modlogset')
def check_file():
f = 'data/modlogset/settings.json'
if not fileIO(f, 'check'):
print('Creating default settings.json...')
fileIO(f, 'save', {})
def setup(bot):
check_folder()
check_file()
q = ModLog(bot)
loop = asyncio.get_event_loop()
loop.create_task(q.purge_modlog())
bot.add_cog(q)
To loop the event under def def setup(bot): You can see
loop = asyncio.get_event_loop()
loop.create_task(q.purge_modlog())
This is supposed to loop the event (q.purge_modlog()) I'm not sure what I'm doing wrong here. I have already tried the follow (q.purge_modlog(ctx, number))
line 686, in setup
loop.create_task(q.purge_modlog(ctx, number))
NameError: name 'ctx' is not defined
If anyone could help me that would be great. To add this is a module.
I have corrected some mistakes here. Try to read through the discord.py documentation on purging messages.
class ModLog:
def __init__(self, bot):
self.bot = bot
async def on_ready(self):
await self.bot.wait_until_ready()
for server in self.bot.servers:
channel = self.bot.get_channel("channel ID here")
if channel:
self.bot.loop.create_task(self.modlog_purge(channel))
async def modlog_purge(self, channel):
while True:
now = datetime.utcnow()
two_weeks_ago = now - timedelta(days=14)
await self.bot.purge_from(channel, before=two_weeks_ago)
await asyncio.sleep(86400)
def setup(bot):
q = ModLog(bot)
bot.add_cog(q)
class ModLog:
def __init__(self, bot):
self.bot = bot
async def on_ready(self):
await self.bot.wait_until_ready()
for guild in self.bot.guilds:
channel = await self.get_channel(guild)
if channel:
self.bot.loop.create_task(self.modlog_purge(channel))
async def get_channel(guild):
# Whatever your logic for getting the Channel for a given guild is
async def modlog_purge(self, channel):
while True:
now = datetime.utcnow()
two_weeks_ago = now - timedelta(days=14)
await channel.purge(before=two_weeks_ago)
await asyncio.sleep(86400)
def setup(bot):
q = ModLog(bot)
bot.add_cog(q)
Here's how I would structure this (I'm not on a computer with discord.py at the moment, so there may be some errors). We have an on_ready event that kicks off background tasks for each server that has a channel we want to maintain (this could instead loop through a list of channels, or something similar).
The actual purge is all taken care of by the TextChannel.purge coroutine. We just pass it a datetime object, and it deletes 100 messages from before that date (this is configurable). It then sleeps for a day and repeats.

Categories

Resources