Display row from psycopg2 in readable format - python

I am fetching a number of records from postgres using python tkinter and displaying the same on an layout , the code which I am using for fetching and listing using listbox is as below :
def get_search(id):
conn = psycopg2.connect(dbname="postgres", user="postgres", password="passw0rd", host="localhost", port="5432")
cur = conn.cursor()
query = 'select * from table where id=%s;'
cur.execute(query, (id,))
row = cur.fetchall()
listbox = Listbox(frame, width=20, height=1)
listbox.grid(row=9, column=1)
listbox.insert(END, row)
listbox = Listbox(frame, width=20, height=10)
listbox.grid(row=9, column=1)
for x in row:
listbox.insert(END, x)
conn.commit()
conn.close()
However, the data which is displaying is just plain simple and blank space is as delimiter.
Is it feasible to add further in listbox or using something else so that either each column for each row shows separately in individual box or the column values can be separated by a different delimiter.

Related

Python Tkinter text entry box to insert data to SQL Server

I have created a small python tkinter program designed to have a user write data into text entry boxes in the app then insert this data into a MS SQL server database. When clicking the insert button I am getting the following error message, stopping the app from insert the code into SQL.
cursor.execute("INSERT INTO TEST_DISA_MAIN_TABLE VALUES (:DENSITY_VALUE, :DATE, :TIME, :CHART_VALUE)",
pyodbc.ProgrammingError: ('The SQL contains 0 parameter markers, but 1 parameters were supplied', 'HY000')*
This is my code for the python insert function:
def insertvalue():
# Create a database or connect to one
conn = pyodbc.connect('Driver={SQL Server};'
'Server=MON-SQL-02;'
'Database=ENVIRONMENTAL;'
'Trusted_Connection=yes;')
# Create cursor
cursor = conn.cursor()
# Insert into table
cursor.execute("INSERT INTO TEST_DISA_MAIN_TABLE VALUES (:DENSITY_VALUE, :DATE, :TIME, :CHART_VALUE)",
{
'DENSITY_VALUE': DENSITY_VALUE.get(),
'DATE': DATE.get(),
'TIME': TIME.get(),
'CHART_VALUE': CHART_VALUE.get(),
})
# Commit changes
conn.commit()
#Close Connection
conn.close()
# Clear the text boxes
DENSITY_VALUE.delete(0, END)
DATE.delete(0, END)
TIME.delete(0, END)
CHART_VALUE.delete(0, END)
#Create text boxes
DENSITY_VALUE = Entry(root, width=30)
DENSITY_VALUE.grid(row=2, column=1)
DATE = Entry(root, width=30)
DATE.grid(row=3, column=1)
TIME = Entry(root, width=30)
TIME.grid(row=4, column=1)
CHART_VALUE = Entry(root, width=30)
CHART_VALUE.grid(row=5, column=1)
#Create Text box labels
DENSITY_VALUE_Label = Label(root, text="Density Value")
DENSITY_VALUE_Label.grid(row=2, column=0)
DATE_Label = Label(root, text="Date")
DATE_Label.grid(row=3, column=0)
TIME_Label = Label(root, text="Time")
TIME_Label.grid(row=4, column=0)
CHART_VALUE_Label = Label(root, text="Chart Value")
CHART_VALUE_Label.grid(row=5, column=0)
button = Button(root, text = "Show All Values", command = showvalues)
button.grid(row=0, column=0)
button = Button(root, text = "Insert Values", command = insertvalue)
button.grid(row=1, column=0)
#Commit changes
conn.commit()
# Close connection
conn.close()
root.mainloop()
I used this format to insert data into a sqlite3 db, but the same format is not working when inserting into a SQL Server database. I have tested the connection to the SQL server and can display values in the app so that part works correctly.

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.

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