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.
Related
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.
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
So I am creating a store management system that utilizes SQLite database.
When I execute the query directly in the SQLite browser, it works, but when I'm using Python, there is no error, but the update doesn't happen. Can you please take a look.
Part where I'm Updating with the left stock:
value1 = int(self.stock) - int(self.qne.get())
sql = "UPDATE products SET stock = " + str(value1) + " WHERE pk = " + str(self.ident.get())
conn.execute(sql)
conn.close()
My full code up to now:
# import random
from tkinter import *
import datetime
import sqlite3
conn = sqlite3.connect('database.db')
products_list = []
quantity_list = []
price_list = []
class Application:
def __init__(self, master):
self.master = master
# today's date
date = datetime.datetime.now()
# frames
self.left = Frame(master, width=800, height=700, bg='white')
self.left.pack(side=LEFT)
self.right = Frame(master, width=400, height=700, bg='steelblue')
self.right.pack(side=RIGHT)
# heading
self.heading = Label(self.left, text="Welcome to Store Management System", font=('arial 40 bold'), fg='steelblue', bg='white')
self.heading.place(x=0, y=0)
# cart
self.cart = Label(self.right, text=("TEST TRADE LINK"), font=('arial 25 bold'), fg='white', bg='steelblue', padx=10, pady=10)
self.cart.place(x=0, y=0)
# datelabel
self.datelabel = Label(self.right, text= (str(date)[:10]), font=('arial 25 bold'), fg='white', bg='steelblue')
self.datelabel.place(x=0,y=55)
# template for bill
self.bpro = Label(self.right, text= "Products", font=('arial 16 bold'), fg='white', bg='steelblue')
self.bpro.place(x=0, y=100)
self.bqua = Label(self.right, text= "Quantity", font=('arial 16 bold'), fg='white', bg='steelblue')
self.bqua.place(x=120, y=100)
self.bpri = Label(self.right, text= "Price", font=('arial 16 bold'), fg='white', bg='steelblue')
self.bpri.place(x=240, y=100)
# label for the input
self.id = Label(self.left, text="Enter Unique ID", font=('arial 16 bold'), bg='white')
self.id.place(x=0, y=80)
# entry for the unique id
self.inp = IntVar()
self.ident = Entry(self.left, width=50, bg='white', textvariable=self.inp)
self.ident.place(x=190, y=82)
# button
self.submit = Button(self.left, text="Submit", width=17, height=2, command=self.ajax)
self.submit.place(x=400, y=125)
# ajax contents
self.products_name = Label(self.left, text="", font=('arial 16 bold'), bg='white')
self.products_name.place(x=0, y=250)
self.price = Label(self.left, text="", font=('arial 16 bold'), bg='white')
self.price.place(x=0, y=290)
self.expiration = Label(self.left, text="", font=('arial 16 bold'), bg='white')
self.expiration.place(x=0, y=330)
# down reached upto y=440
self.total = Label(self.left, text="", font=('arial 16 bold'), bg='white')
self.total.place(x=0, y=480)
def ajax(self):
if self.ident.get() == "0":
print("Failed")
else:
self.result = conn.execute("SELECT * FROM products WHERE pk LIKE ?", [str(self.ident.get())])
for self.row in self.result:
self.product = self.row[1]
self.expd = self.row[4]
self.cost = self.row[3]
self.stock = self.row[2]
self.products_name.configure(text="Product Name: " + str(self.product))
self.price.configure(text="Price Per Unit: Rs. " + str(self.cost) + " \t")
self.expiration.configure(text="Expiration Date: " + str(self.expd))
# new labels and entries
self.qn = Label(self.left, text="Quantity", font=('arial 16 bold'), bg='white')
self.qn.place(x=0, y=370)
self.q = IntVar()
self.qne = Entry(self.left, width=50, bg='white', textvariable=self.q)
self.qne.place(x=150, y=371)
self.discount = Label(self.left, text="Discount", font=('arial 16 bold'), bg='white')
self.discount.place(x=0, y=410)
self.d = IntVar()
self.dise = Entry(self.left, width=50, bg='white', textvariable=self.d)
self.dise.place(x=150, y=410)
self.btnadd = Button(self.left, width=17, height=2, text="Add to Cart", bg='lightblue', command=self.add_to_cart)
self.btnadd.place(x=400, y=440)
self.bill = Button(self.left, width=17, height=2, text='Generate Bill', bg='lightgreen', command=self.print_bill)
self.bill.place(x=200, y=440)
def add_to_cart(self):
products_list.append(self.product)
quantity_list.append(self.qne.get())
price_list.append(int(self.qne.get()) * int(self.cost))
value1 = int(self.stock) - int(self.qne.get())
sql = "UPDATE products SET stock = " + str(value1) + " WHERE pk = " + str(self.ident.get())
conn.execute(sql)
conn.close()
t = 150
i = 0
for p in products_list:
self.pr1 = Label(self.right, text=str(products_list[i]), font=('arial 16 bold'), bg='steelblue', fg='white').place(x=0, y=t)
self.pr2 = Label(self.right, text=(str(quantity_list[i])), font=('arial 16 bold'), bg='steelblue', fg='white').place(x=120, y=t)
self.pr3 = Label(self.right, text=(str(price_list[i])), font=('arial 16 bold'), bg='steelblue', fg='white').place(x=240, y=t)
t += 40
i += 1
print(str(products_list) + str(quantity_list)+ str(price_list))
def print_bill(self):
f = open("bill.txt", 'w+')
f.write(str(products_list) + str(quantity_list) + str(price_list))
f.close()
# reset all after each purchase
# delete the temporary cart
del(products_list[:])
del(quantity_list[:])
del(price_list[:])
# # delete the labels
# self.pr1.configure(text="")
# self.pr2.configure(text="")
# self.pr3.configure(text="")
root = Tk()
b = Application(root)
# root.resizable(False, False)
root.geometry("1200x720+0+0")
root.mainloop()
I had 50 for the first product and I am trying to update it, but when I check it after the update is executed, it shows 50.
My database:
You have to explicitely commit the transaction (most client programs do it automagically for you but not the db-api modules):
value1 = int(self.stock) - int(self.qne.get())
sql = "UPDATE products SET stock = " + str(value1) + " WHERE pk = " + str(self.ident.get())
conn.execute(sql)
conn.commit()
conn.close()
Unrelated, but constructing sql queries that way is not only error prone (escaping issues notably) but also a huge security issue that leaves your code opened to SQL injections.
You want instead to use a cursor and let the db-api take care of properly building the query:
value = int(self.stock) - int(self.qne.get())
id = self.ident.get()
sql = "UPDATE products SET stock=? WHERE pk=?"
cursor = conn.cursor()
cursor.execute(sql, (value, id))
conn.commit()
This and the commit() call are actually well documented
Finally, opening a connection does not come for free so it's better to keep it open as long as possible instead of opening/closing it on each operation.
Ive created a function that creates and packs some drop down menus. the only issue Im now facing is figuring out how to store the selection from all 6 menus into a list? im able to access the menus selection through the func() method, but im stuck as how to store all these? ideally id like to have all 6 selections stored in a list, is this possible?
def func(value):
x = value
print(value)
def GetEntry(x):
var = StringVar()
var.set('select one')
formatted = x.get().split()##gets the entry and forms a list
getMeal = CsvLoadSearch(u, formatted)
meal = OptionMenu(root, var, *getMeal, command = func ).pack()
mealOneButton = Button(root, text = "query database", command = lambda : GetEntry(mealOneString))
mealTwoButton = Button(root, text = "query database", command = lambda : GetEntry(mealTwoString))
mealThreeButton = Button(root, text = "query database", command = lambda : GetEntry(mealThreeString))
mealFourButton = Button(root, text = "query database", command = lambda : GetEntry(mealFourString))
mealFiveButton = Button(root, text = "query database", command = lambda : GetEntry(mealFiveString))
mealSixButton = Button(root, text = "query database", command = lambda : GetEntry(mealSixString))
this is the program bellow:
from tkinter import *
from tkinter import ttk
import csv
import os
u = "C:\\Users\\luke daniels\\Documents\\fooddata.csv"
"""
Loads csv and compares elements from foodList with current row.
returns a list of rows that match elements in foodList.
"""
def CsvLoadSearch(u, foodList):
results = []
inputfile = open(u)
for row in csv.reader(inputfile):
for food in foodList:
if food in row[0]:
results.append(row)
##print(row)
return results
##gets selection from drop down
def func(value):
x = value
def GetEntry(x):
var = StringVar()
var.set('select one')
formatted = x.get().split()##gets the entry and forms a list
getMeal = CsvLoadSearch(u, formatted)
meal = OptionMenu(root, var, *getMeal, command = func ).pack()
root = Tk()
root.title("MacroCalc")
caloriesAim = StringVar()
protien = StringVar()
fat = StringVar()
carbs = StringVar()
mealOneString = StringVar()
mealTwoString = StringVar()
mealThreeString = StringVar()
mealFourString = StringVar()
mealFiveString = StringVar()
mealSixString = StringVar()
mealOneKeyword = Entry(root, textvariable = mealOneString)
mealTwoKeyword = Entry(root, textvariable = mealTwoString)
mealThreeKeyword = Entry(root, textvariable = mealThreeString)
mealFourKeyword = Entry(root, textvariable = mealFourString)
mealFiveKeyword = Entry(root, textvariable = mealFiveString)
mealSixKeyword = Entry(root, textvariable = mealSixString)
mealLabel = Label(root,text = "meals")
mealLabel.config(font=("Courier", 30))
mealLabel.pack()
mealLone = Label(root,text = "meal one")
mealLtwo = Label(root,text = "meal two")
mealLthree = Label(root,text = "meal three")
mealLfour = Label(root,text = "meal four")
mealLfive = Label(root,text = "meal five")
mealLsix = Label(root,text = "meal six")
caloriesLabel = Label(root,text = "calories needed").pack()
calories = Text(root, height = 1, width = 10).pack()
protienLabel= Label(root,text = "protien ratio").pack()
protien = Text(root, height = 1, width = 4).pack()
carbsLabel = Label(root,text = "carbohydrate ratio").pack()
carbs = Text(root, height = 1, width = 4).pack()
fatsLabel = Label(root,text = "fats ratio").pack()
fats = Text(root, height = 1, width = 4).pack()
displayText = Text(root).pack(side = RIGHT)
mealOneButton = Button(root, text = "query database", command = lambda : GetEntry(mealOneString))
mealTwoButton = Button(root, text = "query database", command = lambda : GetEntry(mealTwoString))
mealThreeButton = Button(root, text = "query database", command = lambda : GetEntry(mealThreeString))
mealFourButton = Button(root, text = "query database", command = lambda : GetEntry(mealFourString))
mealFiveButton = Button(root, text = "query database", command = lambda : GetEntry(mealFiveString))
mealSixButton = Button(root, text = "query database", command = lambda : GetEntry(mealSixString))
mealButtons = [mealOneButton, mealTwoButton, mealThreeButton, mealFourButton, mealFiveButton, mealSixButton]
mealKeywords = [mealOneKeyword, mealTwoKeyword, mealThreeKeyword, mealFourKeyword, mealFiveKeyword, mealSixKeyword]
mealLabels = [mealLone, mealLtwo, mealLthree, mealLfour, mealLfive, mealLsix]
##packs the drop downs and respective lables
i = 0
while i < len(mealLabels):
mealLabels[i].pack()
mealKeywords[i].pack()
mealButtons[i].pack()
##meal.pack()
i = i + 1
root.mainloop()
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.