I am trying to write a program that asks for a user input of either a first name and last name or a customer ID in a sql database. The first part if the user inputs a customer ID, I seem to have figured out, and the program runs and outputs desired output. However, if the user inputs the choice to do it by name, the program works up until when it is supposed to output the results of the sql query. At which point the program just ends. I can't seem to figure out why it is not outputting the sql query for the lift of me. Here is my code:
while (True): # Begins a while loop to validate the user inputs a correct value.
ui = input("Would you like to lookup the customer by Customer ID (1) or Name (2)? >")
try: # Tries to convert the users input into an integer if possible
ui = int(ui)
except: # If not possible it informs the user their input was invalid and tries again.
print("Invalid selection.")
if (ui == 1): # Breaks the while loop if a valid input is detected.
break
elif (ui == 2): # Breaks the while loop if a valid input is detected.
break
else:
print("Please enter either 1 or 2 to make a selection.")
if(ui == 1):
while(True):
cid = input("What is the Customer ID? >")
try: # Attempts to turn the input into an integer.
cid = int(cid)
cursor.execute("SELECT C.CustID, C.Fname, C.Lname, C.Gender, C.CustState, U.Population FROM Customer C INNER JOIN USState U ON C.CustState = U.StateID WHERE C.CustID = %d" % (cid))
for x in cursor: # If a valid integer is entered for customer ID, a SQL Query is outputted with the results matching the CustID.
print("Customer ID: %d, First Name: %s, Last Name: %s, Gender: %s, State: %s, State Population: %s." %(x[0],x[1],x[2],x[3],x[4],int(x[5])))
break # The while loop is broken.
except:
print("Please enter an integer.")
elif(ui == 2):
cid = input("What is the customer's first name? (press enter for blank) >")
xid = input("What is the customer's last name?")
cursor.execute("SELECT C.CustID, C.Fname, C.Lname, C.Gender, C.CustState, U.Population FROM Customer C INNER JOIN USState U ON C.CustState = U.StateID WHERE C.Fname = '%s' AND C.Lname = '%s'" % (cid, xid))
for x in cursor:
print("Customer ID: %d, First Name: %s, Last Name: %s, Gender: %s, State: %s, State Population: %s." %(x[0],x[1],x[2],x[3],x[4],int(x[5])))
Related
It shows no error and is able to run, but the data in the SQLite table doesn't update. However other update function similar to this work
def seller_edit():
while True:
sellername = str(input("Enter your username: "))
with sqlite3.connect(r"C:\Users\User\Desktop\HFSystem\Assginment\HFuserinfo.db") as connect:
cursor = connect.cursor()
check = "SELECT * FROM sellerinfo WHERE Username = ?"
cursor.execute(check,[sellername])
results = cursor.fetchall()
if results:
Phone = int(input("Enter New Phone No.: "))
Email = str(input("Enter New Email: "))
Address = str(input("Enter New Address: "))
updateseller ="""UPDATE sellerinfo SET Phone = ?, Email=?,Address=? WHERE Username=?"""
cursor.execute(updateseller,[sellername,Phone,Email,Address])
connect.commit()
print("Seller Info Edited!")
connect.close()
seller_info_menu()
break
else:
print("ProductID does not recognised")
option = input("Do you want to try again (y/n): ")
if option.lower() == "n":
seller_info_menu()
break
The order of the parameters inside the tuple of the 2nd argument of cursor.execute() must be the same as the order of the ? paceholders:
cursor.execute(updateseller, (Phone, Email, Address, sellername))
I am currently creating a main menu that acts like a bank account.
def main_menu():
print("Main Menu")
print("0 - Quit")
print("1 - Open Account")
print("2 - Check Balance")
print("3 - Close Account")
loop = True
while loop:
main_menu()
choice = input("Enter your choice: ")
choice = int(choice)
if choice == 0:
exit(loop)
elif choice == 1:
name_on_account = input("Name on account: ")
balance = float(input("Enter Initial Balance: "))
print("---Account successfully created---")
print("Account number:", account_no())
print("Name on account:", name_on_account)
print("Balance:", balance)
print("Account opened on:", now)
cur.execute("""
INSERT INTO account(name_on_account, balance) VALUES
("%s", "%s");""", (name_on_account, balance))
connection.commit()
elif choice == 2:
print("Checking account balance")
account_number = input("Enter account number: ")
print("---Checking account balance---")
print("Account number:", account_number)
cur.execute("""SELECT * from account;
""")
account_no1 = cur.fetchone()
for i in account_no1[0]:
if account_number == i:
cur.execute("""select name_on_account from account where account_no = "%s";
""", (account_number,))
name1 = cur.fetchone()
print(name1)
name2 = ''.join(map(str,name1))
name3 = int(name2)
print("Name on account:", name3)
cur.execute("""select balance from account where account_no = "%s";
""", account_number)
balance1 = cur.fetchone()
balance2 = ''.join(map(str,balance1))
balance3 = int(balance2)
print("Balance:", balance3)
cur.expecute("""select account_open_date from account where account no = "%s";
""", account_number)
date1 = cur.fetchone()
date2 = ''.join(map(str, date1))
date3 = int(date2)
print("Account opened on:", date3)
connection.commit()
else:
print("Error: Invalid account number")
I'm not worried about option 3 as of right now, but I am having trouble with option 2.
When a person pick option 1, they will input their name and the amount of money deposited in their bank account.
This information will be stored in the mysql table account(account_no, name_on_account, balance, account_open_date, account_status).
This means that account_no is auto-incremented, account_open_date is default as curdate(), and account_status is default to be "open").
In option 2 however, when a person input their account number; it should return back all of their information how it is displayed in the option 1.
What I am having trouble with is, how do you efficiently iterate over the person's information using fetchone() and be able to get the specific column information with (account_no = account_number) (if you do have a better suggestion on a better way to implement this, please comment below)
This is the error message that I get:
Traceback (most recent call last):
File "(deleted for privacy purposes)"
for i in account_no1[0]:
TypeError: 'int' object is not iterable
Thank you for the help!
pymysql (and most other python mysql clients) is returning a tuple when you invoke fetchone(), and each entry in the tuple matches up to the datatypes defined in the table that you're querying. So let's look at your code:
elif choice == 2:
print("Checking account balance")
account_number = input("Enter account number: ")
print("---Checking account balance---")
print("Account number:", account_number)
cur.execute("""SELECT * from account""")
account_no1 = cur.fetchone()
for i in account_no1[0]:
Here you're querying all columns and all rows from the account table, reading the first row, and then iterating over whatever is in the first column of that row. But that's probably just an id column, which is probably why you're getting the error that you're getting: integers are not iterable. That'd be like writing for i in 10, Python doesn't understand what that means
If you want to iterate over all of the returned rows, you can do that like this:
cur.execute("""SELECT * from account;
""")
for row i in cur.fetchall():
# Each iteration "row" is a tuple of values corresponding to the table's columns
That's kind of silly though. You'd returning all of the rows from the database and then iterating over them and looking for a specific account number. Why not just do that as part of your query?
nrows = cur.execute("SELECT * from account where account_no=%s", (account_number,))
if nrows == 0:
# Account number not found, do something
else:
row = curs.fetchone()
# row now contains all of the values from the discovered
Note that you don't need to put quotation marks around %s placeholders, and you don't need semicolons. The client does all of this conversion for you.
Also note that you should not select * from tables. What if the table definition changes to include more columns? Just select the handful of columns that you actually need, then if more columns are added to the table later your code won't need to be changed at all and you won't be requesting more data than you need. So more like:
nrows = cur.execute("SELECT name, balance, date_opened from account where account_no=%s", (account_number,))
if nrows > 0:
name, balance, date_opened = curs.fetchone()
The aim of this code is to achieve the following:
-Enter username
-Check if exists on DB
-If not create new user
-Add currency & balance to new user row
The issue is with my insert statement. I'm not sure how to use the WHERE condition while inserting data using defined variables. Help would be welcomed!
Error Message: TypeError: function takes at most 2 arguments (4 given)
def add_user():strong text
print("enter new username")
UserLogin = str(input())
c.execute("SELECT username FROM FinanceDBTable")
enter code here
for row in c.fetchall():
print()
#Convers tuple to string without spaces
UserNameDB = ''.join(row)
if UserNameDB == UserLogin:
print('This username already exisits. please try again')
add_user()
else:
print("Please enter your balanace\n")
userbalance = input()
print("Please enter currency\n")
userCurrency = input()
c.execute("INSERT INTO FinanceDBTable (balance, currency) VALUES (?,?)",
(userbalance, userCurrency), "WHERE (username) VALUES (?)", (UserLogin))
conn.commit()
One way would be to do this, also does not use recursion which is seen as unpythonic and also will eventually throw errors. Plus made it a bit more pythonic.
I'm not sure if you can use WHERE in INSERT statements, you can in UPDATE maybe that where you're getting that idea from, but by also giving the username value with the other will work for what you are trying to achieve i think.
def add_user():
while True:
username = input("Username: ")
c.execute("SELECT username FROM FinanceDBTable WHERE username = ?", (username,))
results = c.fetchall()
if len(results) < 1:
# Add user as there is not user with that username.
user_balance = int(input("Please enter your balance: "))
user_currency = input("Please enter currency: ")
c.execute("INSERT INTO FinanceDBTable(username, balance, currency) VALUES (?,?,?)", (username, user_balance, user_currency))
conn.commit()
break
else:
# User already exists
print('This username already exists, please try again.')
I have a function within my "students' test" program.
This function reads out either the "highest score", "lowest score" or "average score" when you enter the student's name and class number.
The first two parts work but i can't seem to get the average working, when i read a value from a database it never returns like i would prefer it to, it returns it like: [(6,) , (3,)].
This is the function below:
def readScore():
selection = input("What score would you like the read ? \n 1 - Lowest score \n 2 - Highest score \n 3 - Average score... ")
name = input("Please enter the name of the pupil...")
classNo = input("Please enter the class of the pupil...")
myFile = sqlite3.connect("scores.db")
c = myFile.cursor()
c.execute('SELECT score FROM scores WHERE name = (?) AND classNo = (?)', (name, classNo,))
row = c.fetchall()
print(row)
try:
if selection == "1":
print (min(row))
if selection == "2":
print (max(row))
if selection == "3":
print (sum(row) /len(row))
except:
print("No scores for that student")
myFile.commit()
myFile.close()
You could compute the average in your program, but it would be a better idea to avoid fetching all rows, and to let the database compute these values:
c.execute('SELECT MIN(score) FROM ...') # or
c.execute('SELECT MAX(score) FROM ...') # or
c.execute('SELECT AVG(score) FROM ...')
row = c.fetchone()
print(row[0])
I'm trying to enter details into an SQL database through Python. I have already created the database with fields customerID, firstname, surname, town and telephone.
When running this function, I get the error 'str' object is not callablefor the line where I am trying to INSERT the values of the variables.
import sqlite3
#function used to add a new customer, once confirmed save the customer in a
#customer list
def add_customer():
#open up the clients database
new_db = sqlite3.connect('clients.db')
#create a new cursor object to be able to use the database
c = clients_db.cursor()
print("Add customer")
firstname = ""
while len(firstname) == 0:
firstname = input("Enter the customer's first name: ")
surname = ""
while len(surname) == 0:
surname = input("Enter the customer's surname: ")
town = ""
while len(town) == 0:
town=input("Enter the customer's town: ")
telephone = '1'
while len(telephone) != 11:
while telephone[0] != '0':
telephone = input("Please enter the customer's telephone number: ")
if telephone[0] != '0':
print ("telephone numbers must begin with zero")
elif len(telephone) != 11:
print("must have 11 numbers")
#check that data has been entered
print(firstname,surname,town,telephone)
#insert data into the customer table
c.execute('INSERT INTO Customer VALUES (NULL, ?,?,?,?,)'(firstname, surname, town, telephone))
print("Customer added successfully ...")
clients_db.commit()
clients_db.close()
if choice ==1:
another = input("Would you like to add another? yes [y] or no [n] --> ")
if another=='y':
add_customer()
else:
main_menu()
You forgot a comma between the SQL statement string and the parameters:
c.execute('INSERT INTO Customer VALUES (NULL, ?,?,?,?,)'(firstname, surname, town, telephone))
# ^
so you effectively do this: "some string"(arg1, arg2, ...), trying to treat the string as a function.
Simply insert a comma there:
c.execute(
'INSERT INTO Customer VALUES (NULL, ?,?,?,?,)',
(firstname, surname, town, telephone))