Parameterized SQLite Table Insertion via Python? - python-3.x

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

Related

passing one function to another inside a for loop

New to programming. I wrote a program that Asks the user to enter the name, age and shoe size for four people and adds it to a dictionary. In fact, it works even when I don't use one function as an argument for another function. However, when i try to pass get_user_info() to store_user_info it doesnt work. I also tried to pass get_user_info to three separate variables and then passed these variables to store_user_info and it still didn't work. I am probably making a dumb error. Sorry its kind of a basic type of query but I just started learning programming. Any guidance is appreciated.
FOLLOWING CODE DOESN'T WORK: IT RUNS THE FOR LOOP BUT NEVER PROMPTS FOR THE INPUT FOR MORE THAN ONCE
#get user info
def get_user_info():
while True:
try:
user_input_name = (input("What is your name "))
user_input_age = int(input("How old are you "))
user_input_shoesize = float(input("What is your show size "))
break
except (ValueError,IndexError):
print('wrong selection or input')
return user_input_name,user_input_age,user_input_shoesize
#Store user info
def store_user_info(user_info):
user_information = {}
for i in range(3):
name, age, shoesize = user_info
user_information[name] = {"age" : age,"shoesize": shoesize}
print(user_information)
return user_information
=
store_user_info(get_user_info())
YET THE FOLLOWING WORKS and the loop works 3 times as expected:
#get user info
def get_user_info():
while True:
try:
user_input_name = (input("What is your name "))
user_input_age = int(input("How old are you "))
user_input_shoesize = float(input("What is your show size "))
break
except (ValueError,IndexError):
print('wrong selection or input')
return user_input_name,user_input_age,user_input_shoesize
#Store user info
def store_user_info():
user_information = {}
for i in range(3):
name, age, shoesize = get_user_info()
user_information[name] = {"age" : age,"shoesize": shoesize}
print(user_information)
return user_information
store_user_info()

How can I use something stored in a DataBase? SQLite / Python

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

cant get my while loops working the way i want it to

i am trying to get this code to work properly where if you input a number it will revert you back to the name=input prompt and once you enter alphabetical characters and not numerical characters it will allow you to move on to the next set of code but it keeps returning you to the name = input and doesnt let you through the rest of the code
def setup():
global name
global HP
global SP
global MP
while True:
try:
name = input('can you please tell me your name? ')
name2=int(name)
if not name.isalpha==True and not name2.isdigit==False:
break
except Exception:
print('please input your name')
continue
HP = randint(17,20)
SP = randint(17,20)
MP = randint(17,20)
print('welcome ['+name+':]: to the moon landing expedition')
There is a problem at name2=int(name) This causes an exception unless you type all numbers. In turn, this triggers the Exception and loops it forever. Your while loop seems fine.
What i think you should do:
while True:
name = input('What is your name')
isnum = False
for i in name:
if i.isnumeric():
isnum = True
break
if isnum:
print('Please type your name.')
continue
break

Cx_Oracle fetch crash

So I've queried data from oracle database using cursor.execute(). A relatively simple select query. It works.
But when I try to fetch data from it, python crashes.
The same occurs for fetchall(), fetchmany() and fetchone().
When the query first broke in fetchmany() I decided to loop through fetchone() and it worked for the first two rows then broke at the third.
I'm guessing it is because there's too much data in third row.
So, is there any way to bypass this issue and pull the data?
(Please ignore the wrong indents could not copy properly in my phone)
EDIT:
I removed four columns with type "ROWID". There was no issue after that. I was easily able to fetch 100 rows in one go.
So to confirm my suspicion I went ahead and created another copy with only those rowed columns and it crashes as expected.
So is there any issue with ROWID type?
Test table for the same.
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvAEyAAB0HOAAM','AAAL0DAEzAAClz7AAN','AAAVeuABHAAA4vdAAH','ABoeo+AIVAAE6dKAAQ');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvABQAABKo6AAI','AAAL0DAEzAAClz7AAO','AAAVeuABHAAA4vdAAH','ABoeo+AIVAAE6dKAAQ');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvABQAABKo6AAG','AAAL0DAEzAAClz7AAP','AAAVeuABHAAA4vdAAH','ABoeo+AHIAAN+OIAAM');
Insert into TEST_FOR_CX_ORACLE (Z$OEX0_LINES,Z$OEX0_ORDER_INVOICES,Z$OEX0_ORDERS,Z$ITEM_ROWID) values ('ABoeqvAEyAAB0HOAAK','AAAL0DAEzAACl0EAAC','AAAVeuABHAAA4vdAAH','ABoeo+AHIAAN+OIAAM');
Script:
from cx_Oracle import makedsn,connect,Cursor
from pandas import read_sql_table, DataFrame, Series
from time import time
def create_conn( host_link , port , service_name , user_name , password ):
dsn=makedsn(host_link,port,service_name=service_name)
return connect(user=user_name, password=password, dsn=dsn)
def initiate_connection(conn):
try:
dbconnection = create_conn(*conn)
print('Connected to '+conn[2]+' !')
except Exception as e:
print(e)
dbconnection = None
return dbconnection
def execute_query(query,conn):
dbconnection=initiate_connection(conn)
try:
cursor = dbconnection.cursor()
print ('Cursor Created!')
return cursor.execute(query)
except Exception as e:
print(e)
return None
start_time = time()
query='''SELECT * FROM test_for_cx_oracle'''
try:
cx_read_query = execute_query(query,ecspat_c)
time_after_execute_query = time()
print('Query Executed')
columns = [i[0] for i in cx_read_query.description]
time_after_getting_columns = time()
except Exception as e:
print(e)
print(time_after_execute_query-start_time,time_after_getting_columns-time_after_execute_query)
Unfortunately, this is a bug in the Oracle Client libraries. You will see it if you attempt to fetch the same rowid value multiple times in consecutive rows. If you avoid that situation all is well. You can also set the environment variable ORA_OCI_NO_OPTIMIZED_FETCH to the value 1 before you run the query to avoid the problem.
This has been reported earlier here: https://github.com/oracle/python-cx_Oracle/issues/120

Python3 and Sqlite3 can't Insert

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

Resources