Query in function is not executing - python

I am trying to create a button where you can delete a record selected using trv.bind. I can select fine as I already tried using print to display the OID when selecting but when I add a delete function, it does nothing and gives me no errors. From my understanding I am selecting the specific row through the OID but my function does not delete. The query is not executing.
I made a sample code that mirrors mine.
import tkinter
from tkinter import *
from tkinter import ttk, LabelFrame, StringVar
import tkinter.messagebox
import sqlite3
#cursor
conn = sqlite3.connect('newtest.db')
#cursor is needed for sql functions
c = conn.cursor()
top = tkinter.Tk()
q = StringVar()
t1 = StringVar()
t2 = StringVar()
#this grabs each ID
def getrows(event):
rowid = trv.identify_row(event.y)
item = trv.item(trv.focus())
t1.set(item['values'][0])
t2.set(item['values'][1])
def pdelete():
oid = t1.get()
query = "DELETE FROM products WHERE oid = "+oid
c.execute(query)
conn.commit()
def update(show):
trv.delete(*trv.get_children())
for i in show:
trv.insert("", 'end', values=i)
return show
conn.commit()
def query_database():
query = "SELECT oid, pdesc from products"
conn = sqlite3.connect('newtest.db')
c = conn.cursor()
c.execute(query)
show = c.fetchall()
return show
box4 = LabelFrame(top, text="Products Summary")
box4.pack (fill="both", expand="yes", padx=20, pady=10)
trv = ttk.Treeview(box4, column=(1,2), show="headings", height="20")
style=ttk.Style(trv)
style.configure('Treeview', rowheight=20)
trv.pack(side=LEFT)
trv.heading(1, text="Product ID")
trv.heading(2, text="Product Description")
conn = sqlite3.connect('newtest.db')
query = "SELECT oid, pdesc from products"
c.execute(query)
show = c.fetchall()
update(show)
#deletebutton
btn6 = ttk.Button(box4, text='Delete', command=pdelete)
btn6.pack(side=RIGHT)
#select
trv.bind('<Double 1>', getrows)
top.title("deletetest")
top.geometry("1500x1200")
top.mainloop()

Related

How to create a search bar for a table from DB Browser

I'm trying to find a way to create a search bar for a table connected to a DB Browser database. The search bar I'm looking for is the one where you type in the bar, and the program will "hide" any data that does not follow the "requirements" while leaving the ones that do visible. The following code shows what I've tried so far. Hopefully, I made myself clear, and thank you for your help. I don't know how to attach the database so sorry for the inconvenience.
If you remove the code between the '''Triple Apostrophes,''' you should see a table with a button that says SELECT which reveals the data. The Table shown is where I would like the Search bar to control.
Thank you for your help once again.
from tkinter import ttk
import tkinter as tk
from tkinter import *
import sqlite3
ws = Tk()
ws.title('Directory')
ws.geometry('600x400')
ws.attributes('-topmost', True)
ws.attributes('-fullscreen', True)
'''
def Scankey(event):
val = event.widget.get()
print(val)
if val == '':
data = Table1
else:
data = []
for item in Table1:
if val.lower() in item.lower():
data.append(item)
Update(data)
def Update(data):
listbox.delete(0, 'end')
# put new data
for item in data:
listbox.insert('end', item)
ws = Tk()
entry = Entry(was)
entry.pack()
entry.bind('<KeyRelease>', Scankey)
listbox = Listbox(was)
listbox.pack()
Update()
# Connect to the database
def connect():
conn = sqlite3.connect("MEMBERinformation.db")
cur = conn.cursor()
cur.execute(
"CREATE TABLE IF NOT EXISTS ChurchMemberInformation(MemberID TEXT PRIMARY KEY, "
"FirstName TEXT, LastName TEXT)")
conn.commit()
conn.close()
# Populate Treeview table
def View():
conn = sqlite3.connect("MEMBERinformation.db")
cur = conn.cursor()
cur.execute("SELECT FirstName, LastName FROM ChurchMemberInformation")
rows = cur.fetchall()
for row in rows:
print(row) # print all records in the database
tree.insert("", tk.END, values=row)
conn.close()
#Frame
Table1 = Frame(was)
Table1.pack(anchor=CENTER)
# Connect the database
connect()
# Create Treeview widget
tree = ttk.Treeview(Table1, column=("column1", "column2",), show='headings')
tree['columns'] = ('FIRST NAME', 'LAST NAME')
tree.column('FIRST NAME', width=100)
tree.heading("#1", text="FIRST NAME")
tree.column('LAST NAME', width=100)
tree.heading("#2", text="LAST NAME")
tree.pack()
# Create and pack buttons
button1 = tk.Button(text="SELECT", command=View)
button2 = tk.Button(text="QUIT", command=ws.destroy)
button1.pack()
button2.pack()
ws.mainloop()

Getting data from MySQL using tkinter button gets duplicated

I've a python script that uses tkinter and a button to get data from MySQL but every time I press the button the data gets duplicated like that:
Code below:
from tkinter import ttk
import tkinter as tk
import mysql.connector
def View():
mydb = mysql.connector.connect(
host="localhost",
user="",
password="",
database=""
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM patients")
rows = mycursor.fetchall()
for row in rows:
print(row)
tree.insert("", tk.END, values=row)
mydb.close()
# connect to the database
root = tk.Tk()
root.geometry("900x350")
tree = ttk.Treeview(root, column=("c1", "c2", "c3"), show='headings')
tree.column("#1", anchor=tk.CENTER)
tree.heading("#1", text="ID")
tree.column("#2", anchor=tk.CENTER)
tree.heading("#2", text="First Name")
tree.column("#3", anchor=tk.CENTER)
tree.heading("#3", text="Country")
tree.pack()
button1 = tk.Button(text="Display data", command=View)
button1.pack()
root.mainloop()
How can I make it print/get the data after clearing the last fetched data?
Regards,
You can do a simple check, if there are items inside and then delete all the items, and if not insert, like:
def View():
if len(tree.get_children()): # If there are items inside
tree.delete(*tree.get_children()) # Delete all the items
else:
# Paste the rest of code
You can also define a flag and then check if data is inserted, and proceed accordingly, like:
inserted = False # Initially False
def View():
if inserted:
tree.delete(*tree.get_children())
inserted = False # Set it to not inserted
if not inserted: # Let this get triggered
# Same code
for row in rows:
print(row)
tree.insert("", tk.END, values=row)
mydb.close()
inserted = True # Set it to true.

Saving entries on tkinter to sqlite3

thanks in advance for any help!
Ive been looking online for a solution and have struggled to find one. Im trying to save some data from a entry text box on tkinter to a table in SQLite3 but am getting the same error every time no matter what I try. Code below.
please note, I only started to learn coding from youtube videos a few days ago. apologies if this is really simple!
**python file code**
from tkinter import *
import sqlite3
import tkinter.messagebox
# connect to database
conn = sqlite3.connect("RMS.db")
c = conn.cursor()
# tkinter window
class Application:
def __init__(self, master):
self.master = master
# Creating frames in the master
self.left = Frame(master, width=200, height=60, bg="grey")
self.left.pack(side=LEFT)
self.right = Frame(master, width=0, height=0, bg="grey")
self.right.pack(side=RIGHT)
# labels for window
self.driverlevel = Label(self.left, text="Driver Level:", font="calabri 12 bold", fg="white", bg="grey")
self.driverlevel.place(x=1, y=2)
# Entries for left window
self.driverlevel_ent = Entry(self.left, width=20)
self.driverlevel_ent.place(x=5, y=27)
# Save Button
self.submit = Button(self.left, text="Add", font="calabri 12 bold", fg="white", bg="grey", command=self.addlevel)
self.submit.place(x=140, y=15)
def addlevel(self):
self.val1 = self.driverlevel_ent.get()
if self.val1 == "":
tkinter.messagebox.showinfo("Warning", "Please Enter a Value")
else:
sql = "INSERT INTO 'driverlevel' (Level,) VALUES(?,)"
c.execute(sql, (self.val1))
conn.commit()
tkinter.messagebox.showinfo("Success", "Driver Level Added")
# objects
root = Tk()
b = Application(root)
root.geometry("200x60+0+0")
root.resizable(False, False)
root.title("Add Driver Level")
root.mainloop()
**error message when saving**
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\*****\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/Users/*****/PycharmProjects/******/driverlevel.py", line 41, in addlevel
c.execute(sql, (self.val1))
sqlite3.OperationalError: near ")": syntax error
no idea how to overcome this..
Thanks, Josh
You inserted , after Level, and ?, which was suppose to be this "INSERT INTO 'driverlevel' (Level) VALUES(?) then insert the comma , at the end of (self.val1,) to see it as a tuple because you can insert data into sqlite3 as tuple
You can also insert the data this way
sql = "INSERT INTO driverlevel (Level) VALUES(?,)"
conn = sqlite3.connect("RMS.db")
c = conn.cursor()
c.execute("INSERT INTO driverlevel(level)VALUES(?)", (self.val1,))
conn.commit()
tkinter.messagebox.showinfo("Success", "Driver Level Added")
Make sure you closed the db after insertion.
Full code
from tkinter import *
import sqlite3
import tkinter.messagebox
# connect to database
conn = sqlite3.connect("RMS.db")
c = conn.cursor()
c.execute("CREATE TABLE IF NOT EXISTS driverlevel(level text, age text)")
conn.commit()
conn.close()
# tkinter window
class Application:
def __init__(self, master):
self.master = master
# Creating frames in the master
self.left = Frame(master, width=200, height=60, bg="grey")
self.left.pack(side=LEFT)
self.right = Frame(master, width=0, height=0, bg="grey")
self.right.pack(side=RIGHT)
# labels for window
self.driverlevel = Label(self.left, text="Driver Level:", font="calabri 12 bold", fg="white", bg="grey")
self.driverlevel.place(x=1, y=2)
# Entries for left window
self.driverlevel_ent = Entry(self.left, width=20)
self.driverlevel_ent.place(x=5, y=27)
# Save Button
self.submit = Button(self.left, text="Add", font="calabri 12 bold", fg="white", bg="grey", command=self.addlevel)
self.submit.place(x=140, y=15)
def addlevel(self):
self.val1 = self.driverlevel_ent.get()
if self.val1 == "":
tkinter.messagebox.showinfo("Warning", "Please Enter a Value")
else:
#sql = "INSERT INTO driverlevel (Level) VALUES(?,)"
# conn = sqlite3.connect("RMS.db")
# c = conn.cursor()
# c.execute("INSERT INTO driverlevel(level)VALUES(?)", (self.val1,))
# conn.commit()
# tkinter.messagebox.showinfo("Success", "Driver Level Added")
conn = sqlite3.connect("RMS.db")
c = conn.cursor()
sql = "INSERT INTO 'driverlevel' (Level) VALUES(?)"
c.execute(sql, (self.val1,))
conn.commit()
conn.close()
tkinter.messagebox.showinfo("Success", "Driver Level Added")
# objects
root = Tk()
b = Application(root)
root.geometry("200x60+0+0")
root.resizable(False, False)
root.title("Add Driver Level")
root.mainloop()

How to display entry widget content in Treeview

Am trying to display content entered into entry widget in treeview after saving it in sqlite3 db.The content saved into db but doesn't display the id,Fist name and Surname contents in the treeview.
Your suggestion are welcome to achieve this.
from tkinter import ttk
import tkinter as tk
import sqlite3
def connect():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY,
First TEXT, Surname TEXT)")
conn.commit()
conn.close()
def Insert():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
fr=cur.execute("INSERT INTO profile (First, Surname) VALUES(?, ?)",
(first_text.get(), surname_text.get()))
conn.commit()
for items in fr:
tree.insert('', tk.END, values=items)
conn.close()
connect() # this to create the db
root = tk.Tk()
root.geometry("400x400")
tree= ttk.Treeview(root, column=("column", "colunn1"))
tree.heading("#0", text="NUMBER")
tree.heading("#1", text="FIRST NAME")
tree.heading("#2", text="SURNAME")
tree.pack()
first_text = tk.StringVar()
e1 = tk.Entry(root, textvariable=first_text)
e1.pack()
surname_text = tk.StringVar()
e2 = tk.Entry(root, textvariable=surname_text)
e2.pack()
b1 = tk.Button(text="add data", command=Insert)
b1.pack(side=tk.BOTTOM)
root.mainloop()
The problem in your code is that for items in fr does not work. Python sees fr as an empty iterable (put a print statement in the for loop and you will see that it is never executed). So, to insert the data in the treeview, you can get it directly from the entries and retrieve the db id with cur.lastrowid (I have found this solution in the answer to the question How to retrieve inserted id after inserting row in SQLite using Python?):
from tkinter import ttk
import tkinter as tk
import sqlite3
def connect():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY, First TEXT, Surname TEXT)")
conn.commit()
conn.close()
def Insert():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
data = (first_text.get(), surname_text.get())
# insert data in db
cur.execute("INSERT INTO profile (First, Surname) VALUES(?, ?)", data)
conn.commit()
# insert data in treeview
tree.insert('', tk.END, text=str(cur.lastrowid), values=data)
conn.close()
connect() # this to create the db
root = tk.Tk()
root.geometry("400x400")
tree= ttk.Treeview(root, column=("column", "colunn1"))
tree.heading("#0", text="NUMBER")
tree.heading("#1", text="FIRST NAME")
tree.heading("#2", text="SURNAME")
tree.pack()
first_text = tk.StringVar()
e1 = tk.Entry(root, textvariable=first_text)
e1.pack()
surname_text = tk.StringVar()
e2 = tk.Entry(root, textvariable=surname_text)
e2.pack()
b1 = tk.Button(text="add data", command=Insert)
b1.pack(side=tk.BOTTOM)
root.mainloop()
EDIT: If you use the columns '#1', '#2', '#3' to avoid using the special
column '#0', then you need to change a bit Insert: you need to pass the row id in values instead of text.
from tkinter import ttk
import tkinter as tk
import sqlite3
def connect():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY, First TEXT, Surname TEXT)")
conn.commit()
conn.close()
def Insert():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
data = (first_text.get(), surname_text.get())
# insert data in db
cur.execute("INSERT INTO profile (First, Surname) VALUES(?, ?)", data)
conn.commit()
# insert data in treeview
tree.insert('', tk.END, values=(str(cur.lastrowid),) + data)
conn.close()
connect() # this to create the db
root = tk.Tk()
root.geometry("400x400")
tree = ttk.Treeview(root, column=("column1", "column2", "column3"), show='headings')
tree.heading("#1", text="NUMBER")
tree.heading("#2", text="FIRST NAME")
tree.heading("#3", text="SURNAME")
tree.pack()
first_text = tk.StringVar()
e1 = tk.Entry(root, textvariable=first_text)
e1.pack()
surname_text = tk.StringVar()
e2 = tk.Entry(root, textvariable=surname_text)
e2.pack()
b1 = tk.Button(text="add data", command=Insert)
b1.pack(side=tk.BOTTOM)
root.mainloop()

How to update only selected sqlite3 record from tkinter treeview

Am trying to update sqlite3 db selected in tkinter treeview, am able to insert the row of the treeview selected in the entry widget but when i update the record selected it updates all the records in the sqlite3 db. I need your help to update only the record selected in the treeview but not all the records in the sqlite3 db.
from tkinter import ttk
import tkinter as tk
import sqlite3
def connect():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY,
First TEXT, Surname TEXT)")
conn.commit()
conn.close()
def Update():
data1 = first_text.get()
data2 = surname_text.get()
for selected in tree.selection():
e1.insert(0, selected)
e2.insert(0, selected)
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("UPDATE profile SET First=?, Surname=?", (data1, data2))
conn.commit()
conn.close()
def get_selected_row(event):
print(tree.selection()) # this will print the names of the selected rows
for nm in tree.selection():
content = tree.item(nm, 'values')
e1.insert(tk.END, content[1])
e2.insert(tk.END, content[2]) # this will insert in the entry after
connect() # this to create the db
root = tk.Tk()
root.geometry("400x400")
# this will hide the first column
tree= ttk.Treeview(root, column=("column1", "column2", "column3"),
show='headings')
tree.heading("#1", text="NUMBER")
tree.heading("#2", text="FIRST NAME")
tree.heading("#3", text="SURNAME")
tree.pack()
tree.bind("<<TreeviewSelect>>", get_selected_row)
first_text = tk.StringVar()
e1 = tk.Entry(root, textvariable=first_text)
e1.pack()
surname_text = tk.StringVar()
e2 = tk.Entry(root, textvariable=surname_text)
e2.pack()
b2 = tk.Button(text="EDIT PARTICULAR DATA", command=Update)
b2.pack(side=tk.BOTTOM)
root.mainloop()
The issue here is that you don't tell the db which record to update:
cur.execute("UPDATE profile SET First=?, Surname=?", (data1, data2))
so all records are updated. You need to add the record id:
cur.execute("UPDATE profile SET First=?, Surname=? WHERE ID =?", (data1, data2, tree.set(selected, '#1')))
I found the answer on the website https://www.tutorialspoint.com/sqlite/sqlite_update_query.htm.

Categories

Resources