英文:
Incorrect number of binding when trying to delete from a database (Tkinter, SQLite)
问题
以下是您提供的Python代码的翻译部分:
# !/usr/bin/python3
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox as msg
import sqlite3
class ProyectoPooApp:
# Database connection
database_name = r'database_POO.db'
with sqlite3.connect(database_name) as conn:
cursor = conn.cursor()
update = None
def __init__(self, master=None):
# Build ui
self.win = tk.Tk() if master is None else tk.Toplevel(master)
# Function to center the screen
app_w = 1147
app_h = 379
screen_w = self.win.winfo_screenwidth()
screen_h = self.win.winfo_screenheight()
x = (screen_w / 2) - (app_w / 2)
y = (screen_h / 2) - (app_h / 2)
self.win.geometry(f'{app_w}x{app_h}+{int(x)}+{int(y)}')
self.win.configure(background="#dafcfc")
self.win.iconbitmap("icono.ico")
self.win.resizable(False, False)
self.win.title("Conferencia Arquitectura Hexagonal")
self.frame_data = ttk.Frame(self.win)
# Registration frame
self.frame_registration = tk.LabelFrame(self.frame_data, font=("Helvetica", 13, "bold"))
self.frame_registration.configure(
labelanchor="n",
relief="groove",
text='Inscription')
# Identification label
self.label1 = ttk.Label(self.frame_registration)
self.label1.configure(state="normal", text='Identification')
self.label1.grid(column=0, padx="20 10", pady="20 20", row=0, sticky="e")
# Name label
self.label2 = ttk.Label(self.frame_registration)
self.label2.configure(text='Name\t')
self.label2.grid(column=0, padx="20 10", pady="0 20", row=1, sticky="e")
# Address label
self.label3 = ttk.Label(self.frame_registration)
self.label3.configure(text='Address')
self.label3.grid(column=0, padx="20 10", pady="0 20", row=2, sticky="e")
# Cellphone label
self.label4 = ttk.Label(self.frame_registration)
self.label4.configure(text='Cellphone')
self.label4.grid(column=0, padx="20 10", pady="0 20", row=3, sticky="e")
# Entity label
self.label5 = ttk.Label(self.frame_registration)
self.label5.configure(text='Entity')
self.label5.grid(column=0, padx="20 10", pady="0 20", row=4, sticky="e")
# Date label
self.label6 = ttk.Label(self.frame_registration)
self.label6.configure(text='Date')
self.label6.grid(column=0, padx="20 10", pady="0 20", row=5, sticky="e")
# Entry Identification
self.entry_id = ttk.Entry(self.frame_registration)
self.entry_id.configure(width=33)
self.entry_id.grid(column=1, padx="0 20", pady="20 20", row=0)
# Entry name
self.entry_name = ttk.Entry(self.frame_registration)
self.entry_name.configure(width=33)
self.entry_name.grid(column=1, padx="0 20", pady="0 20", row=1)
# Entry address
self.entry_address = ttk.Entry(self.frame_registration)
self.entry_address.configure(width=33)
self.entry_address.grid(column=1, padx="0 20", pady="0 20", row=2)
# Entry cellphone
self.entry_cellphone = ttk.Entry(self.frame_registration)
self.entry_cellphone.configure(width=33)
self.entry_cellphone.grid(column=1, padx="0 20", pady="0 20", row=3)
# Entry entity
self.entry_entity = ttk.Entry(self.frame_registration)
self.entry_entity.configure(width=33)
self.entry_entity.grid(column=1, padx="0 20", pady="0 20", row=4)
# Entry date
self.entry_date = ttk.Entry(self.frame_registration)
self.entry_date.configure(width=33)
self.entry_date.grid(column=1, padx="0 20", pady="0 20", row=5)
# Button frame
self.frame_registration.grid(column=0, row=0)
self.frame_buttons = ttk.Frame(self.frame_data)
self.frame_buttons.configure(height=200, width=200)
# Save button
self.save_button = ttk.Button(self.frame_buttons)
self.save_button.configure(
cursor="hand2", default="normal", text='Save')
self.save_button.grid(column=0, padx="0 5", row=0)
self.save_button.bind("<1>", self.add_Record, add="+")
# Edit button
self.edit_button = ttk.Button(self.frame_buttons)
self.edit_button.configure(cursor="hand2", text='Edit')
self.edit_button.grid(column=1, padx="5 5", row=0)
self.edit_button.bind("<1>", self.edit_TreeView, add="+")
# Delete button
self.delete_button = ttk.Button(self.frame_buttons)
self.delete_button.configure(cursor="hand2", text='Delete')
self.delete_button.grid(column=2, padx="5 5", row=0)
self.delete_button.bind("<1>", self.delete_Record, add="+")
# Cancel button
self.cancel_button = ttk.Button(self.frame_buttons)
self.cancel_button.configure(cursor="hand2", text='Cancel', command=self.clear_Fields)
self.cancel_button.grid(column=3, padx="5 0", row=0, sticky="e")
self.frame_buttons.grid(column=0, pady="10 0", row=1)
self.frame_data.grid(column=0, pady="30 0", row=0, sticky="n")
# Treeview frame
self.frame_treeview = ttk.Frame(self.win)
# Treeview scrollbar
self.scroll_treeview = ttk.Scrollbar(self.frame_treeview)
self.scroll_treeview.configure(orient="vertical")
self.scroll_treeview.grid(column=1, row=0, sticky="ns")
self.style=ttk.Style()
self.style.configure("style.Treeview", highlightthickness=0, bd=0, background='AliceBlue', fieldbackground="Aliceblue", font=('Helvetica',10))
self.style.configure("style.Treeview.Heading", background='Azure', font=('Helvetica', 10,'bold'))
self.style.map("style.treeview", background = [('selected', "Steelblue")])
self.style.layout("style.Treeview", [('style.Treeview.treearea', {'sticky': 'nswe'})])
# Treeview
self.treeview = ttk.Treeview(self.frame_treeview, yscrollcommand=self.scroll_treeview.set, style="style.Treeview")
self.scroll_treeview.config(command
<details>
<summary>英文:</summary>
I have been doing an interface in Python that can add, edit and delete elements from a database and show said database in a ttk treeview. Right now I'm stuck at the function `elimina_Registro`, which is supposed to delete an item from the database and update the treeview when the `boton_eliminar` button is pressed. When I do press the button to call the function, I get an error message that says `sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 6 supplied.` which is weird because the only binding I'm providing is `self.entry_Id.get()`.
Here's the complete code:
!/usr/bin/python3
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox as msg
import sqlite3
class ProyectoPooApp:
#Conexión base de datos
nombre_db = r'datebase_POO.db'
with sqlite3.connect(nombre_db) as conn:
cursor = conn.cursor()
actualiza = None
def __init__(self, master=None):
# Build ui
self.win = tk.Tk() if master is None else tk.Toplevel(master)
#Función centrar pantalla
app_w=1147
app_h=379
screen_w = self.win.winfo_screenwidth()
screen_h = self.win.winfo_screenheight()
x= (screen_w/2)-(app_w/2)
y=(screen_h/2)- (app_h/2)
self.win.geometry(f'{app_w}x{app_h}+{int(x)}+{int(y)}')
self.win.configure(background="#dafcfc")
self.win.iconbitmap("icono.ico")
self.win.resizable(False, False)
self.win.title("Conferencia Arquitectura Hexagonal")
self.frame_datos = ttk.Frame(self.win)
#Frame Iscripción
self.frame_inscripcion = tk.LabelFrame(self.frame_datos, font= ("Helvetica", 13,"bold"))
self.frame_inscripcion
self.frame_inscripcion.configure(
labelanchor="n",
relief="groove",
text='Inscripción')
#Label identificacion
self.label1 = ttk.Label(self.frame_inscripcion)
self.label1.configure(state="normal", text='Identificación')
self.label1.grid(column=0, padx="20 10", pady="20 20", row=0, sticky="e")
#Label nombre
self.label2 = ttk.Label(self.frame_inscripcion)
self.label2.configure(text='Nombre\t')
self.label2.grid(column=0, padx="20 10", pady="0 20", row=1, sticky="e")
#Label direccion
self.label3 = ttk.Label(self.frame_inscripcion)
self.label3.configure(text='Dirección')
self.label3.grid(column=0, padx="20 10", pady="0 20", row=2, sticky="e")
#Label celular
self.label4 = ttk.Label(self.frame_inscripcion)
self.label4.configure(text='Celular')
self.label4.grid(column=0, padx="20 10", pady="0 20", row=3, sticky="e")
#Label entidad
self.label5 = ttk.Label(self.frame_inscripcion)
self.label5.configure(text='Entidad')
self.label5.grid(column=0, padx="20 10", pady="0 20", row=4, sticky="e")
#Label fecha
self.label6 = ttk.Label(self.frame_inscripcion)
self.label6.configure(text='Fecha')
self.label6.grid(column=0, padx="20 10", pady="0 20", row=5, sticky="e")
#Entry Identificacion
self.entry_id = ttk.Entry(self.frame_inscripcion)
self.entry_id.configure(width=33)
self.entry_id.grid(column=1, padx="0 20", pady="20 20", row=0)
#Entry nombre
self.entry_nombre = ttk.Entry(self.frame_inscripcion)
self.entry_nombre.configure(width=33)
self.entry_nombre.grid(column=1, padx="0 20", pady="0 20", row=1)
#Entry dirección
self.entry_direccion = ttk.Entry(self.frame_inscripcion)
self.entry_direccion.configure(width=33)
self.entry_direccion.grid(column=1, padx="0 20", pady="0 20", row=2)
#Entry celular
self.entry_celular = ttk.Entry(self.frame_inscripcion)
self.entry_celular.configure(width=33)
self.entry_celular.grid(column=1, padx="0 20", pady="0 20", row=3)
#Entry entidad
self.entry_entidad = ttk.Entry(self.frame_inscripcion)
self.entry_entidad.configure(width=33)
self.entry_entidad.grid(column=1, padx="0 20", pady="0 20", row=4)
#Entry fecha
self.entry_fecha = ttk.Entry(self.frame_inscripcion)
self.entry_fecha.configure(width=33)
self.entry_fecha.grid(column=1, padx="0 20", pady="0 20", row=5)
#Frame botones
self.frame_inscripcion.grid(column=0, row=0)
self.frame_botones = ttk.Frame(self.frame_datos)
self.frame_botones.configure(height=200, width=200)
#Boton grabar
self.boton_grabar = ttk.Button(self.frame_botones)
self.boton_grabar.configure(
cursor="hand2", default="normal", text='Grabar')
self.boton_grabar.grid(column=0, padx="0 5", row=0)
self.boton_grabar.bind("<1>", self.adiciona_Registro, add="+")
#Boton editar
self.boton_editar = ttk.Button(self.frame_botones)
self.boton_editar.configure(cursor="hand2", text='Editar')
self.boton_editar.grid(column=1, padx="5 5", row=0)
self.boton_editar.bind("<1>", self.edita_tablaTreeView, add="+")
#Boton eliminar
self.boton_eliminar = ttk.Button(self.frame_botones)
self.boton_eliminar.configure(cursor="hand2", text='Eliminar')
self.boton_eliminar.grid(column=2, padx="5 5", row=0)
self.boton_eliminar.bind("<1>", self.elimina_Registro, add="+")
#Boton cancelar
self.boton_cancelar = ttk.Button(self.frame_botones)
self.boton_cancelar.configure(cursor="hand2", text='Cancelar', command= self.limpia_Campos)
self.boton_cancelar.grid(column=3, padx="5 0", row=0, sticky="e")
self.frame_botones.grid(column=0, pady="10 0", row=1)
self.frame_datos.grid(column=0, pady="30 0", row=0, sticky="n")
#Frame treeview
self.frame_treeview = ttk.Frame(self.win)
#Scrollbar treeview
self.scroll_treeview = ttk.Scrollbar(self.frame_treeview)
self.scroll_treeview.configure(orient="vertical")
self.scroll_treeview.grid(column=1, row=0, sticky="ns")
self.style=ttk.Style()
self.style.configure("estilo.Treeview", highlightthickness=0, bd=0, background='AliceBlue', fieldbackground="Aliceblue", font=('Helvetica',10))
self.style.configure("estilo.Treeview.Heading", background='Azure', font=('Helvetica', 10,'bold'))
self.style.map("estilo.treeview", background =[('selected', "Steelblue")])
self.style.layout("estilo.Treeview", [('estilo.Treeview.treearea', {'sticky': 'nswe'})])
#Treeview
self.treeview = ttk.Treeview(self.frame_treeview, yscrollcommand=self.scroll_treeview.set, style = "estilo.Treeview")
self.scroll_treeview.config(command=self.treeview.yview)
self.treeview.bind('<Double-Button-1>', self.edita_tablaTreeView, add="+")
self.treeview.configure(
height=15,
selectmode="browse",
show="headings")
self.treeview_cols = [
'columna_id',
'columna_nombre',
'columna_direccion',
'columna_celular',
'columna_entidad',
'columna_fecha']
self.treeview_dcols = [
'columna_id',
'columna_nombre',
'columna_direccion',
'columna_celular',
'columna_entidad',
'columna_fecha']
self.treeview.configure(
columns=self.treeview_cols,
displaycolumns=self.treeview_dcols)
#Columna id
self.treeview.column(
"columna_id",
anchor="w",
stretch="true",
width=120,
minwidth=20)
#Columna nombre
self.treeview.column(
"columna_nombre",
anchor="w",
stretch="true",
width=120,
minwidth=20)
#Columna direccion
self.treeview.column(
"columna_direccion",
anchor="w",
stretch="true",
width=120,
minwidth=20)
#Columna celular
self.treeview.column(
"columna_celular",
anchor="w",
stretch="true",
width=120,
minwidth=20)
#Columna entidad
self.treeview.column(
"columna_entidad",
anchor="w",
stretch="true",
width=120,
minwidth=20)
#Columna fecha
self.treeview.column(
"columna_fecha",
anchor="w",
stretch="true",
width=120,
minwidth=20)
#Nombres columnas
self.treeview.heading(
"columna_id",
anchor="center",
text='Id')
self.treeview.heading(
"columna_nombre",
anchor="center",
text='Nombre')
self.treeview.heading(
"columna_direccion",
anchor="center",
text='Dirección')
self.treeview.heading(
"columna_celular",
anchor="center",
text='Celular')
self.treeview.heading(
"columna_entidad",
anchor="center",
text='Entidad')
self.treeview.heading(
"columna_fecha",
anchor="center",
text='Fecha')
self.treeview.grid(column=0, row=0)
self.frame_treeview.grid(column=1, row=0)
self.win.rowconfigure(0, pad=40)
self.win.columnconfigure(0, pad=40)
self.win.columnconfigure(1, pad=40)
# Main widget
self.mainwindow = self.win
self.lee_tablaTreeView()
def valida(self):
return (len(self.entry_id.get()) != 0 )
def run(self):
self.mainwindow.mainloop()
def valida_Identificacion(self, event=None):
pass
def valida_Fecha(self, event=None):
pass
def carga_Datos(self, values):
self.entry_id.insert(0, values[0])
self.entry_nombre.insert(0, values[1])
self.entry_direccion.insert(0, values[2])
self.entry_celular.insert(0, values[3])
self.entry_entidad.insert(0, values[4])
self.entry_fecha.insert(0, values[5])
def limpia_Campos(self):
self.actualiza = None
self.entry_id.configure(state = tk.NORMAL)
self.entry_id.delete(0, tk.END)
self.entry_nombre.delete(0, tk.END)
self.entry_direccion.delete(0, tk.END)
self.entry_celular.delete(0, tk.END)
self.entry_entidad.delete(0, tk.END)
self.entry_fecha.delete(0, tk.END)
def run_Query(self, query, parametros = ()):
#Función para ejecutar los Querys a la base de datos
result = self.cursor.execute(query, parametros)
self.conn.commit()
return result
def lee_tablaTreeView(self):
self.treeview.delete(*self.treeview.get_children())
query = 'SELECT rowid, * FROM Asistentes'
self.run_Query(query)
registros = self.cursor.fetchall()
for record in registros:
self.treeview.insert(parent='', index='end', iid=record[0], text='', values=(record[0], record[2], record[3], record[4], record[5], record[6]))
self.conn.commit()
def adiciona_Registro(self, event=None):
#Adiciona un producto a la base de datos
if self.actualiza:
self.actualiza = None
query = 'UPDATE Asistentes SET Id = ?, Nombre = ?, Dirección = ?, Celular = ?, Entidad = ?, Fecha = ? WHERE Id = ?'
parametros = (self.entry_id.get(), self.entry_nombre.get(), self.entry_direccion.get(),
self.entry_celular.get(), self.entry_entidad.get(), self.entry_fecha.get(), self.entry_id.get())
self.run_Query(query, parametros)
msg.showinfo('Ok',' Registro actualizado con éxito')
else:
query = 'INSERT INTO Asistentes VALUES(?, ?, ?, ?, ?, ?)'
parametros = (self.entry_id.get(), self.entry_nombre.get(), self.entry_direccion.get(),
self.entry_celular.get(), self.entry_entidad.get(), self.entry_fecha.get())
if self.valida():
self.run_Query(query, parametros)
msg.showinfo('',f'Registro: {self.entry_id.get()} agregado')
self.limpia_Campos()
else:
msg.showerror("¡Atención!","No puede dejar la identificación vacía")
self.limpia_Campos()
self.lee_tablaTreeView()
self.entry_id.configure(state = tk.NORMAL)
def edita_tablaTreeView(self, event=None):
try:
seleccion = self.treeview.focus()
parametros = self.treeview.item(seleccion, 'values')
self.limpia_Campos()
self.actualiza = True # Esta variable controla la actualización
self.carga_Datos(parametros)
self.entry_id.configure(state = 'readonly')
except IndexError as error:
self.actualiza = None
msg.showerror("¡Atención!",'Por favor seleccione un ítem de la tabla')
return
def elimina_Registro(self, event=None):
#Elimina un producto de la base de datos
if self.actualiza:
self.actualiza = None
elemento = self.treeview.selection()[0]
query = 'DELETE FROM Asistentes WHERE Id = ?'
parametros = (self.entry_id.get())
opcion = msg.askokcancel('¡Atención!', '¿Borrar registro?')
if opcion:
self.treeview.delete(elemento)
self.run_Query(query, parametros)
msg.showinfo('',f'Registro: {self.entry_id.get()} eliminado')
else: msg.showinfo('', 'No se eliminó el registro')
else:
msg.showerror("¡Atención!","Debe seleccionar un registro")
self.limpia_Campos()
self.lee_tablaTreeView()
self.entry_id.configure(state = tk.NORMAL)
if name == "main":
app = ProyectoPooApp()
app.run()
I was expecting for it to simply delete the item and update the treeview. As the only condition I'm providing is that it has to have the requested Id.
</details>
# 答案1
**得分**: 0
你在`parametros = (self.entry_id.get())`中缺少了一个逗号,这是因为在Python中`("foo") == "foo"`,要创建一个包含一个元素的元组,应该使用`("foo",)`。
<details>
<summary>英文:</summary>
You are missing a comma in `parametros = (self.entry_id.get())`, that's because in Python `("foo") == "foo"`, to create a tuple of one element you should use `("foo",)`.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论