Please help me with the global variable - python

So here's my code, I've been following the tutorial from this guy https://www.youtube.com/watch?v=YXPyB4XeYLA&t=13094s
#4:35:30
The part where I stuck on is when he talked about using global variable.
Whenever I press update record, it shows me error message
line 80, in update
'first': f_name_editor.get(),
NameError: name 'f_name_editor' is not defined
So I went back to check the global variable, it says:
Global variable 'f_name_editor' is undefined at the module level
I am out of ideas already and I still cannot figure it out. I followed all the steps and went back and forth to see if I missed anything during the video and I still can't find the problem
Please help me!
from tkinter import *
import sqlite3
root = Tk()
root.title('Family Member List')
root.geometry('400x400')
conn = sqlite3.connect('Family_list.db')
c = conn.cursor()
'''
c.execute("""CREATE TABLE family(
first_name text,
last_name text,
gender text,
occupation text
)
#""")
'''
#Edit function to update record
def edit():
editor = Tk()
editor.title('Update Record')
editor.geometry('400x400')
conn = sqlite3.connect('Family_list.db')
c = conn.cursor()
record_id = delete_box.get()
c.execute("SELECT * FROM family WHERE oid =" + record_id)
records = c.fetchall()
global f_name_editor
f_name_editor = Entry(editor,width=30)
f_name_editor.grid(row=0, column=1, padx=20)
l_name_editor = Entry(editor,width=30)
l_name_editor.grid(row=1, column=1, padx=20)
gender_editor = Entry(editor,width=30)
gender_editor.grid(row=2, column=1, padx=20)
occupation_editor = Entry(editor,width=30)
occupation_editor.grid(row=3, column=1, padx=20)
f_name_label = Label(editor,text= 'First Name')
f_name_label.grid(row=0, column =0)
l_name_label = Label(editor,text= 'Last Name')
l_name_label.grid(row=1, column =0)
gender_label = Label(editor,text= 'Gender')
gender_label.grid(row=2, column =0)
occupation_label = Label(editor,text= 'Occupation')
occupation_label.grid(row=3, column =0)
# LOOP THROUGH RESULT
for record in records:
f_name_editor.insert(0, record[0])
l_name_editor.insert(0, record[1])
gender_editor.insert(0, record[2])
occupation_editor.insert(0, record[3])
#Save Button after edited
edit_btn = Button(editor, text='Save Record', command = update)
edit_btn.grid(row=6, column = 1, columnspan = 2, pady=10, padx = 10, ipadx= 100)
def update():
conn = sqlite3.connect('Family_list.db')
c = conn.cursor()
record_id = delete_box.get()
c.execute('''UPDATE family SET
first_name=:first,
last_name=:last,
gender=:gender,
occupation=:occupation
WHERE oid = :oid''',
{
'first': f_name_editor.get(),
'last': l_name_editor.get(),
'gender': gender_editor.get(),
'occupation': occupation_editor.get(),
'oid': record_id
})
conn.commit()
conn.close()
def delete():
conn = sqlite3.connect('Family_list.db')
c = conn.cursor()
c.execute("DELETE from family WHERE oid=" + delete_box.get())
conn.commit()
conn.close()
def submit():
conn = sqlite3.connect('Family_list.db')
c = conn.cursor()
c.execute("INSERT INTO family VALUES (:f_name,:l_name,:gender,:occupation)",
{
'f_name':f_name.get(),
'l_name':l_name.get(),
'gender': gender.get(),
'occupation': occupation.get(),
})
conn.commit()
conn.close()
f_name.delete(0,END)
l_name.delete(0,END)
gender.delete(0,END)
occupation.delete(0,END)
def query():
conn = sqlite3.connect('Family_list.db')
c = conn.cursor()
c.execute('SELECT *, oid FROM family')
records = c.fetchall()
print(records)
conn.commit()
conn.close()
print_records = ''
for record in records:
print_records += str(record[0]) + " \t "+ str(record[4]) +'\n'
query_label = Label(root,text= print_records)
query_label.grid(row = 8 ,column = 0, columnspan =2 )
f_name = Entry(root,width=30)
f_name.grid(row=0, column=1, padx=20)
l_name = Entry(root,width=30)
l_name.grid(row=1, column=1, padx=20)
gender = Entry(root,width=30)
gender.grid(row=2, column=1, padx=20)
occupation = Entry(root,width=30)
occupation.grid(row=3, column=1, padx=20)
delete_box= Entry(root, width=30)
delete_box.grid(row=9, column = 1)
#create global variable
f_name_label = Label(root,text= 'First Name')
f_name_label.grid(row=0, column =0)
l_name_label = Label(root,text= 'Last Name')
l_name_label.grid(row=1, column =0)
gender_label = Label(root,text= 'Gender')
gender_label.grid(row=2, column =0)
occupation_label = Label(root,text= 'Occupation')
occupation_label.grid(row=3, column =0)
delete_box_label = Label(root, text = 'Select ID Number')
delete_box_label.grid(row=9, column= 0)
#BUTTONS
submit_btn = Button(root,text='Add Record to Database', command= submit)
submit_btn.grid(row = 4, column =0, columnspan=2, pady=10, padx =10, ipadx=100)
query_btn = Button(root, text='Check Submission', command = query)
query_btn.grid(row=5, column = 0, columnspan = 2, pady=10, padx = 10, ipadx= 100)
delete_btn = Button(root, text='Delete Record', command = delete)
delete_btn.grid(row=10, column = 0, columnspan = 2, pady=10, padx = 10, ipadx= 100)
#Update Button
edit_btn = Button(root, text='Update Record', command = update)
edit_btn.grid(row=11, column = 0, columnspan = 2, pady=10, padx = 10, ipadx= 100)
conn.commit()
conn.close()
root.mainloop()

f_name_editor does not exist in global scope until the edit function creates it. The codepath that calls the update function does not pass through the edit function, so the global variable does not exist at that point. You could declare it in global scope, but you'll likely find that just leads to more bugs.

Related

How do I fix this error? self.category_id.set(row[1]), IndexError: string index out of range

I'm adding data into sqlite table and when I try to update the table, I'm getting this error 'string index not in range'.
Again when I execute the update command, all the columns gets updated except the identity column but my intention is only to update a selected row.
what I not doing right from the code below>
Your assistance will be highly appreciated.
The error is happening in the function update_record(self).
This is my code:
import tkinter
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
import sqlite3
root =Tk()
root.title('Accounting App')
root.config(bg='#3d6466')
root.geometry("520x400")
root.resizable(False, False)
style = ttk.Style()
style.theme_use('alt')
style.configure("TCombobox", fieldbackground="Grey", background="Grey")
class Backend():
def __init__(self):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
#self.conn.execute("""DROP TABLE IF EXISTS account_type""")
self.conn.execute("""CREATE TABLE IF NOT EXISTS account_type(
id INTEGER PRIMARY KEY,
category_id INTEGER NOT NULL,
category_type TEXT NOT NULL
)"""),
self.conn.commit()
# elf.conn.close()
# =========Account Type======
class Account_type():
def insert_account_type(self, category_id, category_type):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
self.cur.execute("""INSERT INTO account_type(category_id,category_type) VALUES(?,?);""",
(category_id, category_type,))
self.conn.commit()
self.conn.close()
def view_account_type(self):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
self.cur.execute("SELECT * FROM account_type")
rows = self.cur.fetchall()
self.conn.close()
return rows
acc_type = Backend.Account_type()
tb = Backend()
class Front_end():
def __init__(self, master):
# Frames
global cur
global conn
conn = sqlite3.connect('accounting.db')
cur = conn.cursor()
# Frames
self.left_frame = LabelFrame(master,bg='#3d6466', relief=SUNKEN,width=200)
self.left_frame.pack(fill = 'both',expand = YES , padx = 5,side=LEFT,anchor=NW)
self.right_frame = LabelFrame(master, bg='#3d6466', relief=SUNKEN)
self.right_frame.pack(fill = 'both',expand = YES ,side=LEFT,anchor=NW)
self.top_right_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN,text='Details',fg='maroon')
self.top_right_frame.pack(fill=BOTH,side=TOP, anchor=NW,expand=YES)
self.top_r_inner_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN, text='...', fg='maroon',height=10)
self.top_r_inner_frame.pack(fill=BOTH, side=TOP, anchor=SW, expand=YES)
self.bottom_right_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN, text='Field View', fg='maroon')
self.bottom_right_frame.pack(fill=BOTH,side=TOP, anchor=SW, expand=YES)
self.my_canvas = Canvas(self.top_right_frame,bg='#3d6466')
self.my_canvas.pack(side=LEFT,fill='both', expand=YES)
# vertical configuration of scrollbar
self.yscrollbar = ttk.Scrollbar(self.top_right_frame, orient=VERTICAL, command = self.my_canvas.yview)
self.yscrollbar.pack(side=RIGHT,fill='both')
self.my_canvas.config(yscrollcommand = self.yscrollbar.set)
self.top_right_frame = Frame(self.my_canvas, bg='#3d6466', relief=SUNKEN)
self.my_canvas.create_window((0,0),window=self.top_right_frame, anchor=NW)
self.my_canvas.bind('<Configure>',lambda e:self.my_canvas.configure(scrollregion = self.my_canvas.bbox('all')))
self.side_frame = LabelFrame(self.left_frame,bg='#3d6466',relief=SUNKEN,text='Menu Buttons',fg='maroon',)
self.side_frame.pack(side=TOP,anchor=NW,expand=YES )
# Side Buttons
self.btn1 = Button(self.side_frame, text='Main Account Types', bg='#3d6466', font=('cambria', 12), anchor=W,
fg='white', width=18,height=2,command=self.main_account)
self.btn1.grid(row=0, column=0, sticky=W)
def main_account(self):
# variables
self.category_id = StringVar()
self.category_type = StringVar()
self.category_search =StringVar()
# functions
def add_main_accounts(self):
if self.category_id.get() == "":
tkinter.messagebox.showinfo('All fields are required')
else:
Backend.Account_type.insert_account_type(self,
self.category_id.get(),self.category_type.get())
tkinter.messagebox.showinfo('Entry successful')
def display_account_types(self):
self.trv.delete(*self.trv.get_children())
for rows in Backend.Account_type.view_account_type(self):
self.trv.insert("", END, values=rows)
def get_account_type(e):
selected_row = self.trv.focus()
data = self.trv.item(selected_row)
row = data["values"]
"""Grab items and send them to entry fields"""
self.category_id.set(row[1])
self.category_type.set(row[2])
def clear(self):
self.category_id.set("")
self.category_type.set("")
**def update_record(self):
selected = self.trv.focus()
self.trv.item(selected, values=(
self.category_id.get(), self.category_type.get()))
conn = sqlite3.connect("accounting.db")
cur = conn.cursor()
if self.category_id.get() == "" or self.category_type.get() == "" :
tkinter.messagebox.showinfo('All fields are required!')
return
update_record = tkinter.messagebox.askyesno('Confirm please',
'Do you want to update records?')
if update_record > 0:
cur.execute(
"UPDATE account_type SET category_id=:cat_id, category_type=:type",
{'cat_id': self.category_id.get(), 'type': self.category_type.get()})
tkinter.messagebox.showinfo('Record update successful!')
conn.commit()**
# call the function for Clearing the fields
clear(self)
conn.close()
"""=================TreeView==============="""
# Scrollbars
ttk.Style().configure("Treeview", background = "#3d6466", foreground = "white", fieldbackground = "grey")
scroll_x = Scrollbar(self.bottom_right_frame, orient = HORIZONTAL)
scroll_x.pack(side = BOTTOM, fill = X)
scroll_y = Scrollbar(self.bottom_right_frame, orient = VERTICAL)
scroll_y.pack(side = RIGHT, fill = Y)
# Treeview columns & setting scrollbars
self.trv = ttk.Treeview(self.bottom_right_frame, height=5, columns=
('id','category_id', 'category_type'), xscrollcommand = scroll_x.set, yscrollcommand = scroll_y.set)
# Treeview style configuration
ttk.Style().configure("Treeview", background = "#3d6466", foreground = "white", fieldbackground = "#3d6466")
# Configure vertical and Horizontal scroll
scroll_x.config(command = self.trv.xview)
scroll_y.config(command = self.trv.yview)
# Treeview Headings/columns
self.trv.heading('id', text = 'NO')
self.trv.heading('category_id', text = 'Category ID')
self.trv.heading('category_type', text = 'Category Type')
self.trv['show'] = 'headings'
# Treeview columns width
self.trv.column('id', width = 50)
self.trv.column('category_id', width = 70)
self.trv.column('category_type', width = 90)
self.trv.pack(fill = BOTH, expand = YES,anchor = NW)
# Binding Treeview with data
self.trv.bind('<<TreeviewSelect>>',get_account_type) # trv.bind('<Double-1>',"")
# Account Types Labels
self.lbl1 = Label(self.top_right_frame,text = 'Category ID',anchor = W,width=12,font = ('cambria',13,),bg = '#3d6466')
self.lbl1.grid(row = 0,column = 0,pady = 5)
self.lbl1 = Label(self.top_right_frame, text='Category Type', anchor=W, width=12, font=('cambria', 13,), bg='#3d6466')
self.lbl1.grid(row=1, column=0, pady=5)
self.lbl2 = Label(self.top_right_frame, text='Search Account', anchor=W, width=12, font=('cambria', 13,),
bg='#3d6466')
self.lbl2.grid(row=6, column=0, pady=5)
# Account Type Entries
self.entry1 = Entry(self.top_right_frame,textvariable = self.category_id,font = ('cambria',13,),bg = 'Grey',width=14)
self.entry1.grid(row = 0,column=1,sticky = W,padx = 4,columnspan=2)
self.entry1 = Entry(self.top_right_frame, textvariable=self.category_type, font=('cambria', 13,), bg='Grey', width=14)
self.entry1.grid(row=1, column=1, sticky=W, padx=4, columnspan=2)
self.entry2 = Entry(self.top_right_frame, textvariable=self.category_search, font=('cambria', 13,), bg='Grey', width=14)
self.entry2.grid(row=6, column=1, sticky=W, padx=4, columnspan=2)
# Buttons
self.btn_1 = Button(self.top_right_frame,text='Add',font=('cambria',12,'bold'),bg='#3d6466',
activebackground='green', fg = 'white',width=12,height = 1,relief=RAISED,
command = lambda :[add_main_accounts(self),display_account_types(self),clear(self)])
self.btn_1.grid(row = 3,column = 0,pady=6, padx=6)
self.btn_2 = Button(self.top_right_frame, text = 'View',command=lambda :[display_account_types(self),clear(self)],
font=('cambria', 12, 'bold'), bg = '#3d6466', activebackground='green',
fg ='white', width=12, height = 1, relief=RAISED)
self.btn_2.grid(row = 3, column=1,padx=0)
self.btn_3 = Button(self.top_right_frame, text = 'Update', command= lambda :[update_record(self),
display_account_types(self)],font=('cambria', 12, 'bold'), bg = '#3d6466',
activebackground = 'green', fg='white', width = 12, height = 1, relief=RAISED)
self.btn_3.grid(row = 4, column = 0,pady=6,padx=10)
# calling the class
app = Front_end(root)
root.mainloop()
Your update function updates all the records exist. To avoid this you should use WHERE. Here its fixed version
def update_record(self):
selected = self.trv.focus()
oldValues = self.trv.item(selected)["values"]
self.trv.item(selected, values=(oldValues[0],
self.category_id.get(), self.category_type.get()))
conn = sqlite3.connect("accounting.db")
cur = conn.cursor()
if self.category_id.get() == "" or self.category_type.get() == "" :
tkinter.messagebox.showinfo('All fields are required!')
return
update_record = tkinter.messagebox.askyesno('Confirm please',
'Do you want to update employee records?')
if update_record > 0:
cur.execute(
"UPDATE account_type SET category_id=:cat_id, category_type=:type WHERE id=:id_value",
{'cat_id': self.category_id.get(), 'type': self.category_type.get(), "id_value": oldValues[0]})
tkinter.messagebox.showinfo('Record update successful!')
conn.commit()
# call the function for Clearing the fields
clear(self)
conn.close()
We used selected rows idx etc.
However your error string index out of range is not about this. The function above going to fix your record update problem. Your error is because it tries to show a record value but after refreshed table, nothing is selected. So it returns empty.
def get_account_type(e):
selected_row = self.trv.focus()
data = self.trv.item(selected_row)
row = data["values"]
if(row == ""):
return
"""Grab items and send them to entry fields"""
self.category_id.set(row[1])
self.category_type.set(row[2])
Now if row is just an empty string, function stops executing and you get no errors.

PYODBC ERROR: SQL data argument out of range (30030) (SQL Bind Parameter)

I am trying to insert data with Python to a DB2 database, here is the code that I have:
window=Tk()
window.title('Seguimiento')
window.geometry("1200x628")
titulo = Label(text="Base de Datos de Seguimiento", font=("Arial", 16, 'bold'), fg="White", bg="Blue")
titulo.pack()
conn_db2 = pyodbc.connect('DSN=AS400; UID=%s; PWD=%s' % ( uname, password ) )
centro_cursor = conn_db2.cursor()
resultado_centro = []
buscar_centro = "SELECT centro FROM BIUMO220.TICKCENTRO"
centro_cursor.execute(buscar_centro)
for loop_centro in centro_cursor:
resultado_centro.append(loop_centro[0])
intervencion_cursor = conn_db2.cursor()
resultado_intervencion = []
buscar_intervencion = "SELECT tipo_intervencion FROM BIUMO220.TICKINTERVENCION"
intervencion_cursor.execute(buscar_intervencion)
for loop_intervencion in intervencion_cursor:
resultado_intervencion.append(loop_intervencion[0])
resultado_intervencion = list(dict.fromkeys(resultado_intervencion))
responsable = StringVar()
fecha = IntVar()
centro = StringVar()
tipo_intervencion = StringVar()
subtipo_intervencion = StringVar()
comentario = StringVar()
ref_producto_final = StringVar()
descripcion_producto_final = StringVar()
ref_componente = StringVar()
util = StringVar()
tiempo_aprox_intervencion = StringVar()
responsable_ = "Responsable: " + uname
hoy = date.today()
global insertar_fecha
insertar_fecha = hoy.strftime("%Y/%m/%d")
fecha_hoy = hoy.strftime("%d/%m/%Y")
fecha_ = "Fecha: " + fecha_hoy
def seleccionar_subtipo(e):
subtipo_intervencion_cursor = conn_db2.cursor()
global resultado_subtipo_intervencion
resultado_subtipo_intervencion = []
seleccion_intervencion = tipo_intervencion_desplegable.get()
buscar_subtipo = "SELECT subtipo FROM BIUMO220.TICKINTERVENCION WHERE
tipo_intervencion = ?"
subtipo_intervencion_cursor.execute(buscar_subtipo, seleccion_intervencion)
for loop_subtipo_intervencion in subtipo_intervencion_cursor:
resultado_subtipo_intervencion.append(loop_subtipo_intervencion[0])
subtipo_intervencion_desplegable.config(value=(resultado_subtipo_intervencion))
def producto_final_descripcion_familia(i):
global res
global ref
cur = conn_db2.cursor()
ref = referencia_producto_final_entrada.get()
res = []
sql = "SELECT E.TEBEZ1, E.TEBEZ2, A.TXTXB1 FROM BIDBD220.TEIL E, BIDBD220.TABDS A WHERE E.TETENR = ? AND A.TXTXRT = 'TL' AND E.TEPRKL = LTRIM(A.TXTXNR) AND A.TXSPCD = 'S'"
cur.execute(sql, ref)
row = cur.fetchall()
for rows in row:
res.append(rows)
descripcion_producto_final_entrada1.config(text=res)
def componente_descripcion_familia(j):
global referencia_componente
global componente_resultado
componente_cursor = conn_db2.cursor()
componente_resultado = []
referencia_componente = referencia_componente_entrada.get()
componente_query = "SELECT E.TEBEZ1, E.TEBEZ2, A.TXTXB1 FROM BIDBD220.TEIL E, BIDBD220.TABDS A WHERE E.TETENR = ? AND A.TXTXRT = 'TL' AND E.TEPRKL = LTRIM(A.TXTXNR) AND A.TXSPCD = 'S'"
componente_cursor.execute(componente_query, referencia_componente)
componente_row = componente_cursor.fetchall()
for com in componente_row:
componente_resultado.append(com)
descripcion_componente_entrada.config(text=componente_resultado)
def util_descripcion_familia(k):
global referencia_util
global util_resultado
util_cursor = conn_db2.cursor()
referencia_util = util_entrada.get()
util_resultado = []
util_query = "SELECT TRIM(E.TEBEZ1), TRIM(E.TEBEZ2), TRIM(A.TXTXB1) FROM BIDBD220.TEIL E, BIDBD220.TABDS A WHERE E.TETENR = ? AND A.TXTXRT = 'TL' AND E.TEPRKL = LTRIM(A.TXTXNR) AND A.TXSPCD = 'S'"
util_cursor.execute(util_query, referencia_util)
util_row = util_cursor.fetchall()
for uti in util_row:
util_resultado.append(uti)
descripcion_util_entrada.config(text=util_resultado)
def registrar_intervencion():
registrar_intervencion_cursor = conn_db2.cursor()
insertar_centro = centro_desplegable.get()
insertar_intervencion = tipo_intervencion_desplegable.get()
insertar_subtipo_intervencion = subtipo_intervencion_desplegable.get()
insertar_comentario = comentario_entrada.get()
insertar_producto_final = referencia_producto_final_entrada.get()
insertar_componente = referencia_producto_final_entrada.get()
insertar_util = util_entrada.get()
insertar_tiempo = tiempo_aprox_intervencion_entrada.get()
** This is the line to intert the form information.**
registrar_intervencion_query = "INSERT INTO BIUMO220.TICKREGINTERVENCION(numerador, responsable, fecha, centro, tipo_intervencion, subtipo, comentario, ref_producto_final, df_producto_final, ref_componente, df_componente, util, df_util, tiempo_intervencion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
registrar_intervencion_cursor.execute(registrar_intervencion_query, (numerador, uname, insertar_fecha, insertar_centro, insertar_intervencion, insertar_subtipo_intervencion, insertar_comentario, insertar_producto_final, res, insertar_componente, componente_resultado, insertar_util, util_resultado, insertar_tiempo))
registrar_intervencion_cursor.commit()
numero_ticket_etiqueta = Label(text="Ticket N:", font=("Arial", 12))
numero_ticket_etiqueta.place(x=20, rely=.1, anchor="w")
global numerador
numerador = 0
responsable_etiqueta = Label(text=responsable_, font=("Arial", 12))
responsable_etiqueta.place(relx=.5, rely=.1, anchor="center")
fecha_etiqueta = Label(text=fecha_, font=("Arial", 12))
fecha_etiqueta.place(x=1100, rely=.1, anchor="e")
tipo_intervencion_etiqueta = Label(text="Tipo de Intervencion:", font=("Arial", 12))
tipo_intervencion_etiqueta.place(x=20, y=100)
tipo_intervencion_desplegable = ttk.Combobox(window, value=resultado_intervencion, font=("Arial", 12))
tipo_intervencion_desplegable.place(x=170, y=100)
tipo_intervencion_desplegable.bind("<<ComboboxSelected>>", seleccionar_subtipo)
subtipo_intervencion_etiqueta = Label(text="Subtipo:", font=("Arial", 12))
subtipo_intervencion_etiqueta.place(x=480, y=100)
subtipo_intervencion_desplegable = ttk.Combobox(window, value=[" "], font=("Arial", 12))
subtipo_intervencion_desplegable.place(x=550, y=100)
centro_etiqueta = Label(text="Centro:", font=("Arial", 12))
centro_etiqueta.place(x=850, y=100)
centro_desplegable = ttk.Combobox(window, value=resultado_centro, font=("Arial", 12))
centro_desplegable.place(x=910, y=100)
comentario_etiqueta = Label(text="Comentario:", font=("Arial", 12))
comentario_etiqueta.place(x=20, y=150)
comentario_entrada = Entry(textvariable=comentario, width="110", font=("Arial", 12))
comentario_entrada.place(x=120, y=150)
referencia_producto_final_etiqueta = Label(text="Ref. Producto Final:", font=("Arial", 12))
referencia_producto_final_etiqueta.place(x=20, y=200)
referencia_producto_final_entrada = Entry(textvariable=ref_producto_final, width="15", font=("Arial", 12))
referencia_producto_final_entrada.place(x=170, y=200)
referencia_producto_final_entrada.bind('<Return>', producto_final_descripcion_familia)
descripcion_producto_final_entrada1 = Label(font=("Arial", 12))
descripcion_producto_final_entrada1.place(x=320, y=200)
descripcion_producto_final_entrada2 = Label(font=("Arial", 12))
descripcion_producto_final_entrada2.place(x=520, y=200)
referencia_componente_etiqueta = Label(text="Ref. Componente:", font=("Arial", 12))
referencia_componente_etiqueta.place(x=20, y=250)
referencia_componente_entrada = Entry(textvariable=ref_componente, width="15", font=("Arial", 12))
referencia_componente_entrada.place(x=160, y=250)
referencia_componente_entrada.bind('<Return>', componente_descripcion_familia)
descripcion_componente_entrada = Label(font=("Arial", 12))
descripcion_componente_entrada.place(x=300, y=250)
util_etiqueta = Label(text="Util:", font=("Arial", 12))
util_etiqueta.place(x=20, y=300)
util_entrada = Entry(textvariable=util, width="15", font=("Arial", 12))
util_entrada.place(x=60, y=300)
util_entrada.bind('<Return>', util_descripcion_familia)
descripcion_util_entrada = Label(font=("Arial", 12))
descripcion_util_entrada.place(x=200, y=300)
tiempo_aprox_intervencion_etiqueta = Label(text="Tiempo Aprox. Intervencion:", font=("Arial", 12))
tiempo_aprox_intervencion_etiqueta.place(x=20, y=350)
tiempo_aprox_intervencion_entrada = Entry(textvariable=tiempo_aprox_intervencion, width="15", font=("Arial", 12))
tiempo_aprox_intervencion_entrada.place(x=220, y=350)
registrar_intervencion_boton = Button(window, text="REGISTRAR", font=("Arial", 12), command=registrar_intervencion)
registrar_intervencion_boton.place(x=20, y=400)
window.mainloop()
And this is my table information:
CREATE TABLE BIUMO220/TICKREGINTERVENCION(
numerador int not null,
responsable char(50) not null,
fecha date not null,
centro char(50) not null,
tipo_intervencion char(50) not null,
subtipo char(50) not null,
comentario char(500),
ref_producto_final char(50),
df_producto_final char(500),
ref_componente char(50),
df_componente char(500),
util char(50),
df_util char(500),
tiempo_intervencion char(5) not null)
I created that table with very huge table fields becasue I thought that the error was because one field was not enough big for the information, but I was wrong.
This is the Python error that i get when trying to insert the information of the form:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\py_install\py_394\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "<string>", line 157, in registrar_intervencion
pyodbc.Error: ('00000', '[00000] [IBM][System i Access ODBC Controller]SQL dat argument out of range. (30030) (SQLBindParameter)')
Incorrect coding was the immediate cause of this symptom:
pyodbc.Error: ('00000', '[00000] [IBM][System i Access ODBC
Controller]SQL dat argument out of range. (30030) (SQLBindParameter)')
You are passing arrays as parameters to the .execute() method, but the interface may expect scalars instead. For example in your code fragment these objects are arrays res and componente_resultado and util_resultado.
It is wise to normalize your data model to store a single scalar value in a specific column. It's unwise to store a list of values in a single column. Any good text book on data modelling will explain the rationale for this, and the consequences of denormalizing to break these rules.
If you choose to denormalize and store a list of values in a single column then you can .join() the array entries to make a scalar (with some delimiter) before supplying the result as a parameter to .execute() as long as you understand this is bad practice and will have consequences and you already ensured the target column is big enough.

Python / Tkinter - Error message when I try to save changes

I am building a database for tools and matrials list in Python using Tkinter for the GUI. I am running into issues when I try to edit data. Everything works until I click the save button in the editor window. It says: sqlite3.ProgrammingError: You did not supply a value for binding 1. Can anyone see what I am doing wrong here?
Here is my code:
from tkinter import *
import sqlite3
mud = Tk()
mud.title("Mud Data")
mud.geometry("400x600")
# Create database
conn = sqlite3.connect('well_sav.db')
# Create cursor
c = conn.cursor()
# Create table
# c.execute("""CREATE TABLE mud (
# mud_type text,
# mud_weight real ,
# mud_viscosity real,
# mud_pit_number real
# )""")
# Create Submit Function for DB
def submit():
# Connect to DB
conn = sqlite3.connect('well_sav.db')
# Create cursor
c = conn.cursor()
# Insert into table
c.execute("INSERT INTO mud VALUES (:mud_type, :mud_weight, :mud_viscosity, :mud_pit_number)",
{
'mud_type': mud_type.get(),
'mud_weight': mud_weight.get(),
'mud_viscosity': mud_viscosity.get(),
'mud_pit_number': mud_pit_number.get()
})
# Commit changes
conn.commit()
# Close connection
conn.close()
# Clear The Text Boxes
mud_type.delete(0, END)
mud_weight.delete(0, END)
mud_viscosity.delete(0, END)
mud_pit_number.delete(0, END)
# Function to edit a record
def edit():
# Create global variables
global editor
global mud_type_editor
global mud_weight_editor
global mud_viscosity_editor
global mud_pit_number_editor
editor = Tk()
editor.title("Edit mud")
editor.geometry("400x200")
conn = sqlite3.connect('well_sav.db')
c = conn.cursor()
record_id = delete_box.get()
c.execute("SELECT * FROM mud WHERE oid = " + record_id)
records = c.fetchall()
mud_type_editor = Entry(editor, width=30)
mud_type_editor.grid(row=0, column=1, pady=(10, 0))
mud_weight_editor = Entry(editor, width=30)
mud_weight_editor.grid(row=1, column=1)
mud_viscosity_editor = Entry(editor, width=30)
mud_viscosity_editor.grid(row=2, column=1)
mud_pit_number_editor = Entry(editor, width=30)
mud_pit_number_editor.grid(row=3, column=1)
# Create Text box Label
mud_type_label = Label(editor, text="Mud Type")
mud_type_label.grid(row=0, column=0, pady=(10, 0))
mud_weight_label = Label(editor, text="Mud Weight")
mud_weight_label.grid(row=1, column=0)
mud_viscosity_label = Label(editor, text="Mud Viscosity")
mud_viscosity_label.grid(row=2, column=0)
mud_pit_number_label = Label(editor, text="Mud Pit Number")
mud_pit_number_label.grid(row=3, column=0)
# Loop through results
for record in records:
mud_type_editor.insert(0, record[0])
mud_weight_editor.insert(0, record[1])
mud_viscosity_editor.insert(0, record[2])
mud_pit_number_editor.insert(0, record[3])
# Create save button
edit_button = Button(editor, text="Save Update", command=update)
edit_button.grid(row=7, column=1, pady=5, padx=5, ipadx=98)
conn.commit()
conn.close()
# Fucntion for updates
def update():
conn = sqlite3.connect('well_sav.db')
c = conn.cursor()
record_id = delete_box.get()
c.execute("""UPDATE mud SET
mud_type = :name,
mud_weight = :length,
mud_viscosity = :inside_diameter,
mud_pit_number = :outside_diameter
WHERE oid = :oid""",
{
'mud_type': mud_type_editor.get(),
'mud_weight': mud_weight_editor.get(),
'mud_viscosity': mud_viscosity_editor.get(),
'mud_pit_number': mud_pit_number_editor.get(),
'oid': record_id
})
conn.commit()
conn.close()
editor.destroy()
# Function to delete a record
def delete():
conn = sqlite3.connect('well_sav.db')
c = conn.cursor()
c.execute("DELETE FROM mud WHERE oid = " + delete_box.get())
conn.commit()
conn.close()
# Create Query Function
def query():
# Connect to DB
conn = sqlite3.connect('well_sav.db')
# Create cursor
c = conn.cursor()
# Query the DB
c.execute("SELECT *, oid FROM mud")
records = c.fetchall()
# print(records)
# Loop through results
print_records = ''
for record in records:
print_records += str(record[0]) + "\t " + str(record[1]) + \
"\t " + str(record[2]) + "\t " + \
str(record[3]) + str(record[4]) + "\n"
query_label = Label(mud, text=print_records)
query_label.grid(row=20, column=0, columnspan=2)
# Commit changes
conn.commit()
# Close connection
conn.close()
# Math Functions
def volume_per_foot(bha_result_text):
bha_gallons_per_foot = float(mud_viscosity.get()) * \
float(mud_viscosity.get()) / 1029.4
bha_result_text.set(str(bha_gallons_per_foot))
# Create Text Boxes
mud_type = Entry(mud, width=30)
mud_type.grid(row=0, column=1, pady=(10, 0))
mud_weight = Entry(mud, width=30)
mud_weight.grid(row=1, column=1)
mud_viscosity = Entry(mud, width=30)
mud_viscosity.grid(row=2, column=1)
mud_pit_number = Entry(mud, width=30)
mud_pit_number.grid(row=3, column=1)
delete_box = Entry(mud, width=30)
delete_box.grid(row=6, column=1)
# Create Text box Label
mud_type_label = Label(mud, text="Mud Type")
mud_type_label.grid(row=0, column=0, pady=(10, 0))
mud_weight_label = Label(mud, text="Mud Weight")
mud_weight_label.grid(row=1, column=0)
mud_viscosity_label = Label(mud, text="Mud Viscosity")
mud_viscosity_label.grid(row=2, column=0)
mud_pit_number_label = Label(mud, text="Pit Number")
mud_pit_number_label.grid(row=3, column=0)
delete_box_label = Label(mud, text="Select ID")
delete_box_label.grid(row=6, column=0)
# Create Submit Button
submit_button = Button(mud, text="Save", command=submit)
submit_button.grid(row=4, column=1, pady=5, padx=5, ipadx=121)
# Create Query Button
query_button = Button(mud, text="Show Muds", command=query)
query_button.grid(row=5, column=1, pady=5, padx=5, ipadx=79)
# Create edit button
edit_button = Button(mud, text="Edit Muds", command=edit)
edit_button.grid(row=7, column=1, pady=5, padx=5, ipadx=87)
# Create delete button
delete_button = Button(mud, text="Delete Mud", command=delete)
delete_button.grid(row=8, column=1, pady=5, padx=5, ipadx=80)
# Commit changes
conn.commit()
# Close connection
conn.close()
mud.mainloop()
And here is the error message:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
return self.func(*args)
File "mud.py", line 123, in update
c.execute("""UPDATE mud SET
sqlite3.ProgrammingError: You did not supply a value for binding 1.
Hi #LoudEye and welcome to Stack Overflow! Try using ? instead of : like this:
c.execute("UPDATE mud SET mud_type=?,mud_weight = ?, mud_viscosity=?, mud_pit_number = ? WHERE...",(mud_type_editor.get(), mud_weight_editor.get(),mud_viscosity_editor.get(),mud_pit_number_editor.get()))
Note: You should also use WHERE also with question mark like I've used with SET

Display multiple user inputs Python

I'm pretty new to Pyton.
So I'm trying to make a gui that displays multiple user inputs. I've managed to do it with two inputs (text and number):
class Product:
db_name = 'mydatabase.db'
def __init__(self, wind):
self.wind=wind
self.wind.title('Date pacienti')
frame = LabelFrame(self.wind, text='Add new record')
frame.grid(row=0, column=1)
Label(frame, text='Name:').grid(row=1, column=1)
self.name = Entry(frame)
self.name.grid(row=1, column =2)
Label(frame, text='Last name:').grid(row=2, column=1)
self.last = Entry(frame)
self.last.grid(row=2, column =2)
Label(frame, text = 'Age:').grid(row=3, column=1)
self.age=Entry(frame)
self.age.grid(row=3, column=2)
Label(frame, text = 'Something else:').grid(row=4, column=1)
self.else=Entry(frame)
self.else.grid(row=4, column=2)
ttk.Button(frame, text='Add record', command = self.adding).grid (row=5,column=2)
self.message=Label(text='', fg='red')
self.message.grid(row=3, column=0)
self.tree = ttk.Treeview (height=10, columns=2)
self.tree.grid(row=7, column=0, columnspan=2)
self.tree.heading('#0',text = 'Name', anchor=W)
self.tree.heading(2, text='Last name', anchor=W)
self.tree.heading(3, text = 'Age', anchor=W)
self.tree.heading(4, text='Something else', anchor=W)
self.viewing_records ()
def run_query(self, query, parameters =()):
with sqlite3.connect (self.db_name) as conn:
cursor = conn.cursor()
query_result = cursor.execute (query, parameters)
conn.commit()
return query_result
def viewing_records (self):
records = self.tree.get_children()
for element in records:
self.tree.delete (element)
query = 'SELECT * FROM pacienti ORDER BY nume DESC'
db_rows = self.run_query (query)
for row in db_rows:
self.tree.insert('', 0, text = row[1], value = row[3])
I want to add more text fields for the user to input (e.g. text = row[2], row[4]... ).
How would I go about it?

How do I fix 'MySQLConverter' object has no attribute '_entry_to_mysql' for inventory input, python-mysql?

I am pretty new to Python, but for a team design project I need to create a code to input information into a Tkinter window that is connected to a mysql table and update that table accordingly. If the same ID is inputted again it should update the quantity +1 :
from Tkinter import*
import tkMessageBox
import tkFont
import mysql.connector
import time
def AddItem():
print "Added Item"
print "ID:" + ID.get()
print "Item Name:" + ItemName.get()
print "Price Per Item:" + PricePerItem.get()
print "Manufacturer:" + Manufacturer.get()
The s = INSERT INTO inventory... is throwing me for a loop, I can input the information into the Tkinter window but when I select the Add Item button, this error shows up:
ProgrammingError: Failed processing format-parameters; 'MySQLConverter' object has no attribute '_entry_to_mysql'
cnx = mysql.connector.connect(user='root',password='cj92cj',
database='INVENTORY', use_unicode=False)
s = "INSERT INTO inventory (ID, Manufacturer, ItemName, PricePerItem, Quantity) VALUES({},{},{},{},1) ON DUPLICATE KEY UPDATE Quantity= Quantity + 1, Manufacturer = VALUES(Manufacturer), ItemName = VALUES(ItemName), PricePerItem = VALUES(PricePerItem);".format(ID.get(),Manufacturer.get(),ItemName.get(),PricePerItem.get())
print ID.get()
print s
cursor = cnx.cursor()
cursor.execute(s, (ID, Manufacturer, ItemName, PricePerItem, Quantity))
cursor.close()
cnx.commit()
cnx.close()
def ClearEntries():
ItemName.delete(0,END)
PricePerItem.delete(0,END)
Manufacturer.delete(0,END)
I have been trying all sorts of things with "s" for hours and hours but I am having trouble figuring out the right syntax to use.
Below is the Tkinter Window code if that helps at all.
def InformationInput():
BigFont=tkFont.Font(family="Arial", size=14, weight="bold")
root.title("Enter Item Information")
root.geometry("1000x400")
root.bind("<Return>", lambda event: AddItem())
lbl1 = Label(root, text="ID:")
lbl2 = Label(root, text="Item Name:")
lbl3 = Label(root, text="Price Per Item:")
lbl4 = Label(root, text="Manufacturer:")
lbl9 = Label(root, text="Enter Item Information", height=3, fg="red", font=BigFont)
global ID, ItemName, PricePerItem, Manufacturer
ID = Entry(root, width=25, textvariable=ID)
ItemName = Entry(root, width=20, textvariable=ItemName)
PricePerItem = Entry(root, width=10, textvariable=PricePerItem)
Manufacturer = Entry(root, width=25, textvariable=Manufacturer)
button1 = Button(root, text="Add Item", command=AddItem, width=15)
button2 = Button(root, text="Clear Entries", command=ClearEntries, width=15)
button3 = Button(root, text="Exit", command=root.destroy, width=15)
lbl9.grid(column=2, row=1, columnspan=5)
lbl1.grid(column = 1, row = 4, sticky="nw")
ID.grid(column = 2, row = 4, sticky="nw")
lbl2.grid(column = 3, row = 4)
ItemName.grid(column = 4, row = 4)
lbl3.grid(column = 5, row = 4)
PricePerItem.grid(column = 6, row = 4, sticky="w")
lbl4.grid(column = 3, row = 10)
Manufacturer.grid(column = 4, row = 10)
button1.grid(column=3, row=15, sticky="e", pady=20)
button2.grid(column=4, row=15)
button3.grid(column=5, row=15, sticky="w")
root = Tk()
ID = IntVar()
ItemName = StringVar()
PricePerItem = IntVar()
Manufacturer = StringVar()
Quantity = IntVar()
InformationInput()
root.mainloop()
You have to use parameter marks in your query or your database driver, in this case MySQL Connector/Python, will through an error. Also, you have to pass values which can be converted. MySQLConverter does not know how to convert entry-objects, so it tells you it can't convert it (although it can be a bit more explicit).
Here is an example (simplified):
s = ("INSERT INTO inventory (ID, Manufacturer, ItemName, PricePerItem, Quantity) "
"VALUES (%s, %s, %s, %s, %s) ON DUP..")
cursor = cnx.cursor()
cursor.execute(s, (ID.get(), Manufacturer.get(), ItemName.get(),
PricePerItem.get(), Quantity.get()))
I took the liberty opening a bug report to improve the error message.
Other remark: I don't think you need to give the ID when inserting? Usually that is an AUTO_INCREMENT.

Categories

Resources