So, I am new at DataBases and I have a question. I first made a re-search in the internet but could not find anything or actually I could not understand correctly what they were explaining. Before starting with my question I want to say that I am currently working in a Discord Bot in Python as Main Language and I am trying to create a per-server-prefix system. I have already made it once but in .JSON format. Then I heard that using .JSON to save this kind of Data is not actually good so I moved to DataBases. Now, my question is:
I have stored the guild_id and prefix in my DB, how could I use that for a per-server-prefix system? I have not tried anything yet except writing the Code to store both Texts. I would really love if anyone could explain to me not just tell me the Code! Any answer will be appreciated <3.
Main.py:
def get_prefix(client, message):
db = sqlite3.connect("main.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT prefix FROM prefixes WHERE guild_id = {message.guild.id}")
result = cursor.fetchone()
if result is None:
return "/"
else:
client = commands.Bot(command_prefix = get_prefix)
Prefixes.py (COGS):
#commands.command()
#commands.has_permissions(administrator=True)
async def prefix(self, ctx, prefix=None):
db = sqlite3.connect("main.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT prefix FROM prefixes WHERE guild_id = ?", ctx.guild.id)
result = cursor.fetchone()
if result is None:
sql = ("INSERT INTO prefixes(guild_id, prefix) VALUES(?,?)")
val = (ctx.guild.id, prefix)
await ctx.channel.send(f"{prefix}")
elif result is not None:
sql = ("UPDATE prefixes SET prefix = ? WHERE guild_id = ?")
val = (prefix, ctx.guild.id)
await ctx.channel.send(f"update `{prefix}`")
cursor.execute(sql, val)
db.commit()
cursor.close()
db.close()
That is pretty much the whole code. If you think anything should be changed or have any suggestions, answer in the comments!
All you need to do is, after the else, put return result. For example:
result = cursor.fetchone()
if result is None:
return "/"
else:
return result
cursor.fetchone() returns a tuple with each element requested in the row, as you only requested the prefix, it will contain just that (e.g: ("!",)) which is permitted as your command_prefix callable can return a string or tuple of strings.
Warning:
You may want to add a check to ensure that someone doesn't specify an empty string (A zero length string with nothing in it) as their prefix, otherwise your bot will attempt to run every message it sees as a command
References: discord.ext.commands.Bot.command_prefix
Related
I have been trying to get a function working to insert a name in to table of users, but for some reason it just isn't working.
import sqlite3
def CreateUser(Name):
try:
sqliteConnection = sqlite3.connect('Expenses.db')
cursor = sqliteConnection.cursor()
make_user = """INSERT INTO Users (Name) VALUES(?);"""
cursor.execute(make_user, Name)
sqliteConnection.commit()
print()
print('User Successfully Created')
print()
# cursor.close()
except sqlite3.Error as error:
print('Failed to Create User', error)
print()
finally:
if (sqliteConnection):
sqliteConnection.close()
print()
escape = input('Press any key to continue.')
Name = input('> ')
CreateUser(Name)
But for some reason it takes the input string and converts it to the sum of every letter in the string. Inputting a name that is a single digit or letter works, but as soon as it's two or more letters, it throws an error of having too many bindings.
I have tried several variations but I just can't seem to get it working. Can anyone point me in the right direction?
Try binding a tuple containing the name, instead of passing the name variable directly:
sqliteConnection = sqlite3.connect('Expenses.db')
cursor = sqliteConnection.cursor()
make_user = """INSERT INTO Users (Name) VALUES(?);"""
cursor.execute(make_user, (Name,)) # change is here
sqliteConnection.commit()
Hi I'm wanting to add a check to a embed field.
Currently when it's None it will just leave a name="Steam" value and a empty value="[{result2[0]}](http://steamcommunity.com/profiles/{result2[0]}).
I'm wanting to make a check to see if result2 is in the database - I put an if statement if result2: before the embed field - if it does not return None it will show the embed field.` If result returns a None Type then don't show the embed field.
Not sure if this is possible.
Here is an example and a mockup edited in paint
The one marked 1 is what results I'm getting if check returns None
The one marked 2 is what result I get if the check returns a not
None
The one marked 3 is mocked up in paint version of what result
I'd like to have if None is returned.
Here is the code I'm working with:
#commands.group(invoke_without_command=True)
async def profile(self, ctx, user: discord.Member=None):
user = user or ctx.author
db = sqlite3.connect('profiles.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT profile FROM profile WHERE username={user.id}")
result = cursor.fetchone()
cursor.execute(f"SELECT steam FROM profile WHERE username={user.id}")
result2 = cursor.fetchone()
if result is None:
await ctx.send(f"{user.display_name}'s bio has not been created yet.")
return
else:
desc = f"**Bio:**\n{(result[0])}"
embed = discord.Embed(title=f"{user.display_name}'s Profile", description=desc, color=user.colour)
if result2: #here I add the check before adding the embed field
embed.add_field(name="Steam", value=f"[{result2[0]}](http://steamcommunity.com/profiles/{result2[0]})")
await ctx.send(embed=embed)
Help would be appreciated.
It looks like result2 is a list containing None, or something similar. Let's directly check result2[0] as well as result2
if result2 and result2[0]:
embed.add_field(name="Steam", value=f"[{result2[0]}](http://steamcommunity.com/profiles/{result2[0]})")
Hi there I'm trying to add checks to my embed definitions that return the users information from the sql database.
What I'd like to achieve is to check if the user has set a gametag and then if the data isn't there then don't show it on their profile.
However, I'm was able to pass a check to see if the user data is in the database if the result is None it will turn Steam None where as I rather not show it altogether.
Here is what I'm working with:
#commands.group(invoke_without_command=True)
async def profile(self, ctx, user: discord.Member=None):
user = user or ctx.author
db = sqlite3.connect('profiles.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT profile FROM profile WHERE username={user.id}")
result = cursor.fetchone()
cursor.execute(f"SELECT steam FROM profile WHERE username={user.id}")
result2 = cursor.fetchone()
if result is None:
await ctx.send(f"{user.display_name}'s bio has not been created yet.")
elif result4:
steam = f"**Steam** [{result2[0]}](http://steam.com/{result2[0]})" #return data from database.
else:
steam = "" # return nothing if nothing returned from database.
desc = f"{(result[0])} \n\n {steam}:" # define a embed description as f-string
embed = discord.Embed(title=f"{user.name}'s Profile", description=desc, color=user.colour)
await ctx.send(embed=embed)```
If I understand correctly, you do not want result2[0] to be None, whereas you are checking for result to be None. Make sure to check for both result2 and result2[0] to be not None and that should fix it.
Also, if that is supposed to stop the embed creation, you might want to return after the await ctx.send(...) (under "if result == None:").
Howdo people,
I'm to put together a limited Q&A program that will allow the user to query Wikidata using SPARQL with very specific/limited query structures.
I've got the program going, but I'm running into issues when entering queries that are formulated differently.
def sparql_query(line):
m = re.search('What is the (.*) of (.*)?', line)
relation = m.group(1)
entity = m.group(2)
wdparams['search'] = entity
json = requests.get(wdapi, wdparams).json()
for result in json['search']:
entity_id = result['id']
wdparams['search'] = relation
wdparams['type'] = 'property'
json = requests.get(wdapi, wdparams).json()
for result in json['search']:
relation_id = result['id']
fire_sparql(entity_id, relation_id)
return fire_sparql
As you can see, this only works with queries following that specific structure, for example "What is the color of night?" Queries along the lines of 'What are the ingredients of pizza?' simply would cause the program to crash because it doesn't follow the 'correct' structure as set in the code. As such, I would like it to be able to differentiate between different types of query structures ("What is.." and "What are.." for example) and still collect the needed information (relation/property and entity).
This setup is required, insofar as I can determine, seeing as the property and entity need to be extracted from the query in order to get the proper results from Wikidata. This is unfortunately also what I'm running into problems with; I can't seem to use 'if' or 'while-or' statements without the code returning all sorts of issues.
So the question being: How can I make the code accept differently formulated queries whilst still retrieving the needed information from them?
Many thanks in advance.
The entirety of the code in case required:
#!/usr/bin/python3
import sys
import requests
import re
def main():
example_queries()
for line in sys.stdin:
line = line.rstrip()
answer = sparql_query(line)
print(answer)
def example_queries():
print("Example query?\n\n Ask your question.\n")
wdapi = 'https://www.wikidata.org/w/api.php'
wdparams = {'action': 'wbsearchentities', 'language': 'en', 'format': 'json'}
def sparql_query(line):
m = re.search('What is the (.*) of (.*)', line)
relation = m.group(1)
entity = m.group(2)
wdparams['search'] = entity
json = requests.get(wdapi, wdparams).json()
for result in json['search']:
entity_id = result['id']
wdparams['search'] = relation
wdparams['type'] = 'property'
json = requests.get(wdapi, wdparams).json()
for result in json['search']:
relation_id = result['id']
fire_sparql(entity_id, relation_id)
return fire_sparql
url = 'https://query.wikidata.org/sparql'
def fire_sparql(ent, rel):
query = 'SELECT * WHERE { wd:' + ent + ' wdt:' + rel + ' ?answer.}'
print(query)
data = requests.get(url, params={'query': query, 'format': 'json'}).json()
for item in data['results']['bindings']:
for key in item:
if item[key]['type'] == 'literal':
print('{} {}'.format(key, item[key]['value']))
else:
print('{} {}'.format(key, item[key]))
if __name__ == "__main__":
main()
I am trying to write a function to do a simple insert.
Here is what I have tried so far
#! /usr/bin/env python3
#import
import sqlite3 as lite
#trying an insert version 1 (does nothing)
def createTableTask():
"""
Create a new table with the name Task
"""
#Connnection to the database and cursor creation
con = lite.connect('./exemple.sqlite')
con.row_factory = lite.Row
cur = con.cursor()
#that does nothing
try:
cur.execute('''CREATE TABLE Tasks (\
Name TEXT PRIMARY KEY, \
Description TEXT, \
Priority TEXT);''')
except lite.IntegrityError as error_SQLite:
print("error: "+ str(error_SQLite))
else:
print("No error has occured.")
con.close();
def insert1():
"""
insert a new task
"""
#Allocating variables data
taskName = 'finish code'
taskDescription = 'debug'
taskPriority = 'normal'
#Connnection to the database and cursor creation
con = lite.connect('./exemple.sqlite')
con.row_factory = lite.Row
cur = con.cursor()
#that does nothing
try:
with con:
cur.execute('''INSERT INTO Tasks (Name, Description, Priority) \
VALUES (?, ?, ?)''', (taskName, taskDescription, taskPriority))
except lite.IntegrityError as error_SQLite:
print("error: "+ str(error_SQLite))
else:
print("No error has occured. but no insert happend ?")
con.close();
def showResult():
"""
Show the result of the insert
"""
con = lite.connect('./exemple.sqlite')
con.row_factory = lite.Row
cur = con.cursor()
cur.execute\
('''SELECT * FROM Tasks ;''')
row = cur.fetchone()
while row:
print(row["Name"], ' | ', row["Description"], ' | ', \
row["Priority"])
row = cur.fetchone()
con.close();
#trying an insert version 2 (this one crash giving :Value error)
def insert2():
"""
insert a new task
"""
#Allocating variables data
taskName = 'finish code'
taskDescription = 'debug'
taskPriority = 'normal'
#Connnection to the database and cursor creation
con = lite.connect('./exemple.sqlite')
con.row_factory = lite.Row
cur = con.cursor()
queryInsert = ('''INSERT INTO Tasks (Name, Description, Priority) \
VALUES (?, ?, ?)''', (taskName, taskDescription, taskPriority))
try:
with con:
cur.execute(queryInsert)
except lite.IntegrityError as error_SQLite:
print("error: "+ str(error_SQLite))
else:
print("No error has occured.")
con.close();
def run():
createTableTask()
insert1()
showResult()
insert2()
showResult()
#calling section
run()
The problem is that none of the insert that I have made so far worked.
The first one does actualy nothing but has a correct syntax
The second one, well it crash.
Here is the output:
spark#spark-Razer-Blade-Pro:~/Documents/testing$ ./exemp.py
No error has occured.
No error has occured. but no insert happend ?
Traceback (most recent call last):
File "./exemp.py", line 98, in
run()
File "./exemp.py", line 94, in run
insert2()
File "./exemp.py", line 83, in insert2
cur.execute(queryInsert)
ValueError: operation parameter must be str
spark#spark-Razer-Blade-Pro:~/Documents/testing$ sqlite3 exemple.sqlite
SQLite version 3.8.2 2013-12-06 14:53:30
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> SELECT * FROM Tasks;
sqlite>
I am looking for the most simple fix and maybe know what is wrong with my code. Because Right now I do not know what is going on with the no insert one. Normally it should, or am I missing something ?
queryInsert = ('''INSERT ...''', (taskName, taskDescription, taskPriority))
This makes queryInsert a tuple with two elements.
But to call the execute method, you need two separate parameters.
You could just unpack the tuple:
cur.execute(*queryInsert)
but it might be clearer to use two separate variables:
queryString = '''INSERT ...'''
queryParams = (taskName, taskDescription, taskPriority)
cur.execute(queryString, queryParams)
ok I got around my error. Just posting it because it might help others.
cur.execute() is a fonction that seek a query as it's first argument, than the other argument are the variables needed for the query.
step one: make the query into a variable without it's parameters
queryString = ''' INSERT INTO someTables rowName, rowName2 ... VALUES (?, ?);'''
there should be as much as ? as there are variables needed. in this exemple I need 2
queryValue1 = 'something'
queryValue2 = '123'
Step 2 to call and execute the query :
cur.execute(queryString, queryValue1, queryValue2)
this should be working without problem