I am trying to make a library management application with the ability of the following: add a book, delete a book, view a book, searching for a book, editing a book all these functions are done on a table (library1) created in a database(called Library) in MYSQL. However I’m unable to update my table in MySQL using Tkinter. It just won’t get updated, I have tried checking where the table name is different but it’s not. It does not produce any errors but the table in mysql is not getting updated however the whole python program works as desired except for the part where the update window should send the updated values of the book to the MYSQL to be changed after fill the values in the form as seen in this picture
Update window after searching for a book by ISBN.
Full code:
import tkinter
import tkinter as tk
from tkinter import *
import mysql.connector
from tkinter import messagebox
import tkcalendar
from PIL import Image, ImageTk
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="Y1234",
database="library"
)
mycursor = mydb.cursor()
def opendeleteWindow():
deletewindow = tk.Toplevel(root)
deletewindow.geometry("600x400")
deletewindow.title("delete window")
maindframe = tk.Frame(deletewindow, width=600, height=400, bg="light yellow")
maindframe.pack_propagate(False)
maindframe.pack()
# dlabel = tk.Label(deletewindow, text="this is the delete window")
# dlabel.pack()
clabel = tk.Label(maindframe, text="enter book code")
clabel.pack(side=tk.TOP)
centry = tk.Entry(maindframe, textvariable=book_c, width=100)
centry.pack(side=tk.TOP)
deletebutton = tk.Button(maindframe, text="delete", font=("Arial", 8), command=lambda: [delete_book(),
deletewindow.destroy()])
deletebutton.place(x=450, y=50)
def opensearchWindow():
searchwindow = tk.Toplevel(root)
searchwindow.geometry("600x400")
searchwindow.title("search window")
mainsframe = tk.Frame(searchwindow, width=600, height=400, bg="light yellow")
mainsframe.grid_propagate(False)
mainsframe.grid(row=0, column=0)
# slabel = tk.Label(searchwindow, text="this is the search window")
# slabel.pack()
book_isbn2 = myentry.get()
mycursor.execute("SELECT * FROM library1 where ISBN='" + book_isbn2 + "'")
headstr = [mycursor.column_names]
hrows = len(headstr)
hcolumns = len(headstr[0])
lst = mycursor.fetchall()
rows = len(lst)
columns = len(lst[0])
for i in range(hrows):
for j in range(hcolumns):
sh = tk.Entry(mainsframe, width=20, fg="black", font=("Arial", 7, "bold"))
sh.grid(row=i, column=j)
sh.insert(tk.END, headstr[i][j])
for i in range(rows):
for j in range(columns):
sh = tk.Entry(mainsframe, width=20, fg="blue", font=("Arial", 7))
sh.grid(row=i + 1, column=j)
sh.insert(tk.END, lst[i][j])
def openviewWindow():
viewwindow = tk.Toplevel(root)
viewwindow.geometry("600x400")
viewwindow.title("view window")
mainvframe = tk.Frame(viewwindow, width=600, height=400, bg="light yellow")
mainvframe.grid_propagate(False)
mainvframe.grid(row=0, column=0)
# vlabel = tk.Label(viewwindow, text="this is the view window")
# vlabel.grid()
mycursor.execute("SELECT * FROM library1")
headstr = [mycursor.column_names]
hrows = len(headstr)
hcolumns = len(headstr[0])
lst = mycursor.fetchall()
rows = len(lst)
columns = len(lst[0])
for i in range(hrows):
for j in range(hcolumns):
sh = tk.Entry(mainvframe, width=20, fg="black", font=("Arial", 7, "bold"))
sh.grid(row=i, column=j)
sh.insert(tk.END, headstr[i][j])
for i in range(rows):
for j in range(columns):
sh = tk.Entry(mainvframe, width=20, fg="blue", font=("Arial", 7))
sh.grid(row=i + 1, column=j)
sh.insert(tk.END, lst[i][j])
button_close = tk.Button(mainvframe, text="Close", font=("Arial", 12), command=viewwindow.destroy)
button_close.place(x=500, y=350)
def openaddWindow():
addwindow = tk.Toplevel(root)
addwindow.geometry("600x400")
addwindow.title("add window")
# alabel = tk.Label(addwindow, text="this is the add window")
# alabel.pack()
mainaframe = tk.Frame(addwindow, width=600, height=400, bg="light yellow")
mainaframe.pack_propagate(False)
mainaframe.pack()
nolabel = tk.Label(mainaframe, text="Book ISBN")
nolabel.place(x=2, y=5)
noentry = tk.Entry(mainaframe, textvariable=book_isbn, width=100)
noentry.place(x=2, y=30)
nalabel = tk.Label(mainaframe, text="Book Name")
nalabel.place(x=2, y=60)
naentry = tk.Entry(mainaframe, textvariable=book_na, width=100)
naentry.place(x=2, y=90)
ylabel = tk.Label(mainaframe, text="Book Date of Issue")
ylabel.place(x=2, y=120)
yentry = tk.Entry(mainaframe, textvariable=book_y, width=80)
yentry.place(x=2, y=150)
yentry = tkcalendar.DateEntry(mainaframe, selectmode="day", date_pattern="YYYY-MM-dd", textvariable=book_y,
width=80)
yentry.place(x=2, y=150)
wlabel = tk.Label(mainaframe, text="Author")
wlabel.place(x=2, y=180)
wentry = tk.Entry(mainaframe, textvariable=writer, width=100)
wentry.place(x=2, y=210)
clabel = tk.Label(mainaframe, text="Book Code")
clabel.place(x=2, y=240)
centry = tk.Entry(mainaframe, textvariable=book_c, width=100)
centry.place(x=2, y=270)
avlabel = tk.Label(mainaframe, text="Book Availability")
avlabel.place(x=2, y=300)
#frame for first radiobutton
frame = tk.Frame(mainaframe)
frame.place(x=2, y=330)
# frame for second radiobutton
book_av.set("none")
aava = Radiobutton(frame, text="Available", variable=book_av, value="Available", bg="tan")
aava.pack(anchor=W)
notava = Radiobutton(frame, text="Not Available", variable=book_av, value="Not Available", bg="tan")
notava.pack(side=LEFT)
buttoninsert = tk.Button(mainaframe, text="Insert Book", font=("Arial", 12), command=lambda: [insert_book(),
addwindow.destroy()])
buttoninsert.place(x=500, y=350)
def open_update_window():
update_window = tk.Toplevel(root)
update_window.geometry("600x400")
update_window.title("Update window")
mainuframe = tk.Frame(update_window, width=600, height=400, bg="light yellow")
mainuframe.grid_propagate(False)
mainuframe.grid(row=0, column=0)
u_nolabel = tk.Label(mainuframe, text="Book ISBN")
u_nolabel.place(x=2, y=5)
u_noentry = tk.Entry(mainuframe, textvariable=book_isbn, width=100)
u_noentry.place(x=2, y=30)
u_nalabel = tk.Label(mainuframe, text="Book Name")
u_nalabel.place(x=2, y=60)
u_naentry = tk.Entry(mainuframe, textvariable=u_book_na, width=100)
u_naentry.place(x=2, y=90)
u_ylabel = tk.Label(mainuframe, text="Book Date of Issue")
u_ylabel.place(x=2, y=120)
u_yentry = tkcalendar.DateEntry(mainuframe, selectmode="day", date_pattern="YYYY-MM-dd", textvariable=u_book_y,width=80)
u_yentry.place(x=2, y=150)
u_wlabel = tk.Label(mainuframe, text="Author")
u_wlabel.place(x=2, y=180)
u_wentry = tk.Entry(mainuframe, textvariable=u_writer, width=100)
u_wentry.place(x=2, y=210)
u_clabel = tk.Label(mainuframe, text="Book Code")
u_clabel.place(x=2, y=240)
u_centry = tk.Entry(mainuframe, textvariable=u_book_c, width=100)
u_centry.place(x=2, y=270)
u_avlabel = tk.Label(mainuframe, text="Book Availability")
u_avlabel.place(x=2, y=300)
# frame fro first radiobutton
frame = tk.Frame(mainuframe)
frame.place(x=2, y=330)
# frame for second radiobutton
u_avvv = u_book_av
aava = Radiobutton(frame, text="Available", variable=u_avvv, value="Available", bg="tan")
aava.pack(anchor=W)
notava = Radiobutton(frame, text="Not Available", variable=u_avvv, value="Not Available", bg="tan")
notava.pack(side=LEFT)
update_button = tk.Button(mainuframe, text="Update Book", command=lambda: [update_book(), update_window.destroy()])
update_button.place(x=500, y=350)
def isbnn_search_window():
isbn_search = tk.Toplevel(root)
isbn_search.geometry("400x400")
isbn_search.title("ISBN Search")
mainsframe =tk.Frame(isbn_search, width=400, height=400, bg="light yellow")
mainsframe.pack_propagate(False)
mainsframe.pack()
isbnlabel = tk.Label(mainsframe, text="Book ISBN to update")
isbnlabel.pack(side=tk.TOP)
global isbnentry
isbnentry= tk.Entry(mainsframe, textvariable=book_isbn, width=80)
isbnentry.pack(side=tk.TOP)
isbnsearchbutton = tk.Button(mainsframe, text="Search for Book to Update", font=("Arial", 8), command=lambda: [search_isbn(),isbn_search.destroy()])
isbnsearchbutton.place(x=300, y=50)
def insert_book():
# nonlocal noentry,naentry, wentry, centry, aventry
b_isbn = book_isbn.get()
b_na = book_na.get()
b_y = book_y.get()
b_w = writer.get()
b_c = book_c.get()
b_av = book_av.get()
if book_isbn.get() == '' or book_na.get() == '' or book_y.get() == '' or book_y.get() == ''
or book_c.get() == '' or book_av.get() == '' :
messagebox.showerror('Error!', 'All Fields of Book''s Details must be entered first too be inserted') # this is to check if all the entry fields are
# empty if it is true it'll show a msgbox error
else:
mycursor.execute(
"INSERT INTO library1(ISBN,NAME,DATE_OF_ISSUE,AUTHOR,CODE,AVAILABILITY) VALUES(%s,%s,%s,%s,%s,%s)",
(b_isbn, b_na, b_y, b_w, b_c, b_av))
mydb.commit()
messagebox.showinfo('Message', 'The book has been inserted to the records!')
mydb.close()
def delete_book():
b_c = book_c.get()
mycursor.execute("delete from library.library1 where CODE='" + b_c + "'")
mydb.commit()
messagebox.showinfo('Message', 'The book has been deleted from the records!')
def update_book():
ub_isbn = book_isbn.get()
ub_na = u_book_na.get()
ub_y = u_book_y.get()
ub_w = u_writer.get()
ub_c = u_book_c.get()
ub_av = u_book_av.get()
update_query = """UPDATE library1 SET NAME = %s, DATE_OF_ISSUE = %s, AUTHOR = %s, CODE = %s, AVAILABILITY = %s
WHERE ISBN = %s"""
inputs = (ub_isbn, ub_na, ub_y, ub_w, ub_c, ub_av)
mycursor.execute(update_query, inputs)
mydb.commit()
messagebox.showinfo("Message", "Book updated successfully")
def search_isbn():
book_search_isbn = isbnentry.get()
mycursor.execute("SELECT * FROM library1 where ISBN='" + book_search_isbn + "'")
lst = mycursor.fetchone()
if lst:
book_isbn.set(lst[0])
open_update_window()
else:
messagebox.showerror("Error", "Book not found")
root = tk.Tk()
root.geometry("600x400")
root.title("library management system")
mainframe = tk.Frame(root, width=600, height=400, bg="light yellow")
mainframe.pack()
topframe = tk.Frame(mainframe, width=600, height=40, bg="light pink", borderwidth=2, relief="sunken")
topframe.pack_propagate(False)
topframe.pack()
centerframe1 = tk.Frame(mainframe, width=400, height=360, bg="light yellow", borderwidth=2, relief="sunken")
centerframe1.pack_propagate(False)
centerframe1.pack(side=tk.LEFT)
centerframe2 = tk.Frame(mainframe, width=200, height=360, bg="light yellow", borderwidth=2, relief="sunken")
centerframe2.pack_propagate(False)
centerframe2.pack(side=tk.RIGHT)
searchbar = tk.LabelFrame(centerframe2, text="search bar", height=60, width=250, bg="light blue")
searchbar.pack(side=tk.TOP, fill=tk.BOTH)
myentry = tk.Entry(searchbar, width=200)
myentry.pack()
searchbutton = tk.Button(searchbar, text="search", font=("Arial", 8), command=opensearchWindow)
searchbutton.pack(side=tk.RIGHT, padx=10)
imagebar = tk.Frame(centerframe1, width=300, height=300)
imagebar.pack_propagate(False)
imagebar.pack(fill=tk.BOTH)
title1 = tk.Label(imagebar, text="hello user this is blabla library for scientific books ", font=("Arial", 13),
bg="light yellow")
title1.pack()
image = Image.open('book.jpeg')
new_image = image.resize((400, 300))
new_image.save('myimage_400.jpeg')
img = ImageTk.PhotoImage(Image.open("myimage_400.jpeg"))
labelimage = tk.Label(imagebar, width=400, height=300, image=img)
labelimage.pack(fill=tk.BOTH)
book_isbn = tk.StringVar()
book_na = tk.StringVar()
book_y = tk.StringVar()
writer = tk.StringVar()
book_c = tk.StringVar()
book_av = tk.StringVar()
u_book_na = tk.StringVar()
u_book_y = tk.StringVar()
u_writer = tk.StringVar()
u_book_c = tk.StringVar()
u_book_av = tk.StringVar()
buttonbook1 = tk.Button(topframe, text="add book", font=("Arial", 12), command=openaddWindow)
buttonbook1.pack(side=tk.LEFT, padx=10)
buttonbook2 = tk.Button(topframe, text="delete book", font=("Arial", 12), command=opendeleteWindow)
buttonbook2.pack(side=tk.LEFT, padx=10)
buttonbook3 = tk.Button(topframe, text="view books", font=("Arial", 12), command=openviewWindow)
buttonbook3.pack(side=tk.LEFT, padx=10)
buttonbook4 = tk.Button(topframe, text="update book", font=("Arial",12), command=isbnn_search_window)
buttonbook4.pack(side=tk.LEFT, padx=10)
root.mainloop()
here is my MYSQL table :
I have tried changing the update query multiple of times and switching the values but it resulted in no good.
2
Answers
Upon further search on the web I found out the query statement used was incorrect and the correct answer is to use :
instead of :
My hunch is that it’s because your function is referencing the new ISBN value that’s been typed into the widget, and trying to use that in the query. The new ISBN wouldn’t exist in the database yet.
You need to keep a reference to the old ISBN number of the record and use that in the update query instead.