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))
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 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])))
I'm new to Python and SQLite3. I've created a database and am attempting to create an add function from user input. The addition to the DB is successful and fully callable through the menu until you exit. When you use the exit method on the menu theres an error and then the data isnt saved to the DB.
import sqlite3
conn = sqlite3.connect("Adventure_Time.db")
c = conn.cursor()
c.execute ("""CREATE TABLE IF NOT EXISTs characters(
first_name text,
last_name text,
email_address text,
phone_number int,
street_address text,
city_name text,
state_name text,
zipcode_number int)
""")
conn.commit()
def display_menu():
print("Welcome to the Adventure Time Database")
print()
print()
print("list - List all of the Records")
print("names - Show First and Last Names")
print("show - All Cities ")
print("add- Add a Character to the Database")
print("exit - Exit program")
print()
def add_charcter():
c = conn.cursor()
try:
first_name = input("First Name: ")
last_name = input("Last Name: ")
email_address = input("Email Address: ")
phone_number = int (input("Telephone Number: "))
street_address = input("Street Address: ")
city_name = input("City: ")
state_name = input("State: ")
zipcode_number = int(input("Zipcode"))
sql = """INSERT INTO characters(
first_name,
last_name,
email_address,
phone_number,
street_address,
city_name,
state_name,
zipcode_number)
VALUES (?,?,?,?,?,?,?,? )
"""
c.execute(sql, (first_name, last_name, email_address, phone_number, street_address,city_name, state_name,zipcode_number))
c.committ()
c.close
print("Record Submitted to Database")
finally:
main()
def main():
display_menu()
while True:
command = input("Command: ")
if command == "list":
list_characters()
elif command == "names":
names_characters()
elif command == "show":
show_contact()
elif command =="add":
add_charcter()
elif command == "exit":
break
else:
print("Not a valid command. Please try again.\n")
conn.close()
print("See you in the Nightosphere!")
if __name__ == "__main__":
main()
c = conn.cursor()
c is cursor object so you can not call commit on it.
you need to call conn.commit()
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()
Function using sqlite3 to bring back data from a table and return #results based on criteria is only returning zero. Running the #function through Visual Studio brings back the expected results but #when I try to run it from the terminal it is interpreting the table #as being an empty list.
import sqlite3
con = sqlite3.connect('test2.db')
cur = con.cursor()
small table to illistrate the problem. Table output is [('Jane', 300.0), ('Joe', 100.0), ('Joe', 50.0)]
total_bal = """SELECT name, amount FROM customers2"""
user_name = input("What is your name? ")
def account_balance(name):
cur.execute(total_bal)
table = cur.execute(total_bal)
total = 0
name = user_name
for t in table:
if t[0] == name:
total += t[1]
return total
print(account_balance(user_name))
expecting to return 150 if user_name input = 'Joe' or 300 if 'Jane'
You could actually just do this with your query and avoid the account balance function all together.
statement = "SELECT name, account FROM customers2 WHERE name = ?;"
name = input("Enter your name: ")
cur.execute(statement, (str(name),))
results = cur.fetchone()
if results:
print(f"Name: {results[0]}\nAccount Balance: {results[1]}"
else:
print("Your name is not in the database")