'Search with LIKE statement in SQLite, with Python and the Tkinter library
I am developing a project, and when it comes to adding a search engine, it does not work correctly, I write something in it and it throws me the following sqlite3 error.
ProgrammingError: Incorrect number of links supplied. The current statement uses 0 and X is provided.
I have declared the search function, and it is assigned to the search button, if I change something in the query it goes blank without yielding any apparent results after clicking on the search button and never gets to show me what it indicates in the search box. Honestly, I have exhausted all my knowledge and got stuck in this step. I would greatly appreciate the help and if you can correctly explain to me where I was failing to move forward. I need the search to update the same treeview
I share my code.
Best regards.
the comment lines below the search function are the other options I was trying
from tkinter import ttk
from tkinter import *
from tkinter import filedialog
import csv
import os
from tkinter import filedialog
from tkinter import messagebox
import sqlite3
class Stock:
# propiedades de la conexion a base de datos---
db_name = 'database.db'
def __init__(self, window):
# Inicializacion
self.Ventana_Principal = window
self.Ventana_Principal.title('Software Prueba')
# Contenedor de Entrada de datos
frame = LabelFrame(self.Ventana_Principal, text = 'Productos--')
frame.grid(row = 0, column = 0, columnspan = 30, padx = 30, pady = 30)
# Entrada de Clave
Label(frame, text = 'Clave: ').grid(row = 1, column = 0)
self.Clave = Entry(frame)
self.Clave.focus()
self.Clave.grid(row = 1, column = 1)
# Entrada de Unidad
Label(frame, text = 'Unidad: ').grid(row = 2, column = 0)
self.Unidad = Entry(frame)
self.Unidad.grid(row = 2, column = 1)
# Entrada de Nombre Producto
Label(frame, text = 'Nombre: ').grid(row = 3, column = 0)
self.Nombre = Entry(frame)
self.Nombre.grid(row = 3, column = 1)
# Entrada de Cantidad
Label(frame, text = 'Cantidad: ').grid(row = 1, column = 2)
self.Cantidad = Entry(frame)
self.Cantidad.grid(row = 1, column = 3)
# Entrada de Precio Compra
Label(frame, text = 'Precio Compra: ').grid(row = 2, column = 2)
self.PrecioCompra = Entry(frame)
self.PrecioCompra.grid(row = 2, column = 3)
# Entrada de Precio Venta
Label(frame, text = 'Precio Venta: ').grid(row = 3, column = 2)
self.PrecioVenta = Entry(frame)
self.PrecioVenta.grid(row = 3, column = 3)
# Boton Agregar Producto - Importar Archivo
ttk.Button(frame, text = 'Guardar Producto', command = self.agregar_productos).grid(row = 10, columnspan = 5, sticky = W + E)
#Seccion de Busqueda
Label(frame, text = 'Buscar: ').grid(row = 4, column = 0)
self.Buscador = Entry(frame, textvariable = StringVar())
self.Buscador.grid(row = 4, column = 1)
Button(frame, text = "Buscar Producto", command = self.buscar_registro).grid(row = 4, column = 2)
# Mensajes de Salida
self.mensaje = Label(text = '', fg = 'red')
self.mensaje.grid(row = 3, column = 5, columnspan = 5, sticky = W + E)
# Tabla
self.tabla = ttk.Treeview(height = 10, columns = ('#1','#2','#3','#4'))
self.tabla.grid(row = 4, column = 5, columnspan = 5)
self.tabla.heading('#0', text = 'Codigo/Clave', anchor = CENTER)
self.tabla.heading('#1', text = 'Producto', anchor = CENTER)
self.tabla.heading('#2', text = 'Cantidad', anchor = CENTER)
self.tabla.heading('#3', text = 'Precio Compra', anchor = CENTER)
self.tabla.heading('#4', text = 'Precio Venta', anchor = CENTER)
# Botones Eliminar - Editar - Importar
ttk.Button(text = 'Editar', command = self.editar_productos).grid(row = 5, column = 5, sticky = W + E)
ttk.Button(text = 'Eliminar', command = self.eliminar_productos).grid(row = 5, column = 9, sticky = W + E)
ttk.Button(text = 'Importar Archivo', command = self.importar_csv).grid(row = 1, column = 7, sticky = W + E)
ttk.Button(text = 'Exportar Archivo', command = self.exportar_csv).grid(row = 2, column = 7, sticky = W + E)
# Ordenando las filas
self.ordenar_productos()
# Funcion a ejecutar en la base de datos --Querys--
def run_query(self, query, parameters = ()):
with sqlite3.connect(self.db_name) as conn:
cursor = conn.cursor()
result = cursor.execute(query, parameters)
conn.commit()
return result
# Leer Tabla de base de datos
def ordenar_productos(self):
# Limpiar Tabla
records = self.tabla.get_children()
for element in records:
self.tabla.delete(element)
# Seleccionar datos
query = 'SELECT * FROM Productos ORDER BY Clave DESC'
db_rows = self.run_query(query)
# Acomodar datos
for row in db_rows:
self.tabla.insert('', 0, text = row[1], values = row[3:7])
def buscar_registro(self):
self.buscar = self.Buscador.get()
query = "SELECT Nombre FROM Productos WHERE Nombre LIKE '%"+self.buscar+"%' ORDER BY Nombre DESC" #"SELECT Nombre FROM Productos WHERE Nombre LIKE '%"+self.Buscador.get()+"%' ORDER BY Nombre DESC"
parameters = (self.buscar)
self.run_query(query, parameters)
self.ordenar_productos()
#palabra = self.Buscador.get()
#query = "SELECT Nombre FROM Productos WHERE Nombre LIKE '%"+self.buscar+"%' ORDER BY Nombre DESC"
#parameters = (self.buscar)
#self.run_query(query, parameters).fetchall()
#self.ordenar_productos()
# Validacion de datos ingresados por el usuario
def validacion(self):
return len(self.Clave.get()) != 0 and len(self.Nombre.get()) != 0 and len(self.Cantidad.get()) != 0 and len(self.PrecioCompra.get()) != 0 and len(self.PrecioVenta.get()) != 0
# Funcion Agregar Productos
def agregar_productos(self):
if self.validacion():
query = 'INSERT INTO Productos VALUES(NULL, ?, ?, ?, ?, ?, ?)'
parameters = (self.Clave.get(), self.Unidad.get(), self.Nombre.get(), self.Cantidad.get(), self.PrecioCompra.get(), self.PrecioVenta.get())
self.run_query(query, parameters)
self.mensaje['text'] = 'Producto {} Se Agrego Correctamente'.format(self.Nombre.get())
self.Clave.delete(0, END)
self.Unidad.delete(0, END)
self.Nombre.delete(0, END)
self.Cantidad.delete(0, END)
self.PrecioCompra.delete(0, END)
self.PrecioVenta.delete(0, END)
else:
self.mensaje['text'] = 'Los Campos no Pueden estar Vacios'
self.ordenar_productos()
# Funcion de Eliminar
def eliminar_productos(self):
self.mensaje['text'] = ''
try:
self.tabla.item(self.tabla.selection())['values'][0]
except IndexError as e:
self.mensaje['text'] = 'Debe Seleccionar un Registro'
return
self.mensaje['text'] = ''
nombre = self.tabla.item(self.tabla.selection())['text']
query = 'DELETE FROM Productos WHERE Clave = ?'
self.run_query(query, (nombre, ))
self.mensaje['text'] = 'Registro {} Eliminado'.format(nombre)
self.ordenar_productos()
# Funcion de Edicion
def editar_productos(self):
self.mensaje['text'] = ''
try:
self.tabla.item(self.tabla.selection())['values'][0]
except IndexError as e:
self.mensaje['text'] = 'Debe Seleccionar un Registro'
return
Nombre_Anterior = self.tabla.item(self.tabla.selection())['values'][0]
Cantidad_Anterior = self.tabla.item(self.tabla.selection())['values'][1]
Precio_Anterior_Compra = self.tabla.item(self.tabla.selection())['values'][2]
Precio_Anterior_Venta = self.tabla.item(self.tabla.selection())['values'][3]
self.Ventana_Edicion = Toplevel()
self.Ventana_Edicion.title ('Editar Producto')
# Nombre Anterior
Label(self.Ventana_Edicion, text = 'Nombre Anterior:').grid(row = 0, column = 1)
Entry(self.Ventana_Edicion, textvariable = StringVar(self.Ventana_Edicion, value = Nombre_Anterior), state = 'readonly').grid(row = 0, column = 2)
# Nuevo Nombre
Label(self.Ventana_Edicion, text = 'Nuevo Nombre:').grid(row = 1, column = 1)
Nuevo_Nombre = Entry(self.Ventana_Edicion)
Nuevo_Nombre.grid(row = 1, column = 2)
# Cantidad Anterior
Label(self.Ventana_Edicion, text = 'Stock Anterior:').grid(row = 2, column = 1)
Entry(self.Ventana_Edicion, textvariable = StringVar(self.Ventana_Edicion, value = Cantidad_Anterior), state = 'readonly').grid(row = 2, column = 2)
# Nueva Cantidad
Label(self.Ventana_Edicion, text = 'Nuevo Stock:').grid(row = 3, column = 1)
Nueva_Cantidad= Entry(self.Ventana_Edicion)
Nueva_Cantidad.grid(row = 3, column = 2)
# Precio Compra Anterior
Label(self.Ventana_Edicion, text = 'Precio Compra Anterior :').grid(row = 0, column = 3)
Entry(self.Ventana_Edicion, textvariable = StringVar(self.Ventana_Edicion, value = Precio_Anterior_Compra), state = 'readonly').grid(row = 0, column = 4)
# Nuevo Precio de Compra
Label(self.Ventana_Edicion, text = 'Nuevo Precio Compra:').grid(row = 1, column = 3)
Nuevo_Precio_Compra= Entry(self.Ventana_Edicion)
Nuevo_Precio_Compra.grid(row = 1, column = 4)
# Precio Venta Anterior
Label(self.Ventana_Edicion, text = 'Precio Venta Anterior:').grid(row = 2, column = 3)
Entry(self.Ventana_Edicion, textvariable = StringVar(self.Ventana_Edicion, value = Precio_Anterior_Venta), state = 'readonly').grid(row = 2, column = 4)
# Nuevo Precio de Venta
Label(self.Ventana_Edicion, text = 'Nuevo Precio Venta:').grid(row = 3, column = 3)
Nuevo_Precio_Venta= Entry(self.Ventana_Edicion)
Nuevo_Precio_Venta.grid(row = 3, column = 4)
# Boton Actualizar
Button(self.Ventana_Edicion, text = 'Actualizar', command = lambda: self.editar_registros(Nuevo_Nombre.get(), Nombre_Anterior, Nueva_Cantidad.get(), Cantidad_Anterior, Nuevo_Precio_Compra.get(), Precio_Anterior_Compra, Nuevo_Precio_Venta.get(), Precio_Anterior_Venta)).grid(row = 8, columnspan = 5, sticky = W + E)
self.Ventana_Edicion.mainloop()
# funcion de edicion
def editar_registros(self, Nuevo_Nombre, Nombre_Anterior, Nueva_Cantidad, Cantidad_Anterior, Nuevo_Precio_Compra, Precio_Anterior_Compra, Nuevo_Precio_Venta, Precio_Anterior_Venta):
query = 'UPDATE Productos SET Nombre = ?, Cantidad = ?, PrecioCompra = ?, PrecioVenta = ? WHERE Nombre = ? AND Cantidad = ? AND PrecioCompra = ? AND PrecioVenta = ?'
parameters = (Nuevo_Nombre, Nueva_Cantidad, Nuevo_Precio_Compra, Nuevo_Precio_Venta, Nombre_Anterior, Cantidad_Anterior, Precio_Anterior_Compra, Precio_Anterior_Venta)
self.run_query(query, parameters)
self.Ventana_Edicion.destroy()
self.mensaje['text'] = 'Registro {} fue Actualizado Correctamente'.format(Nuevo_Nombre)
self.ordenar_productos()
if __name__ == '__main__':
window = Tk()
application = Stock(window)
window.mainloop()
Solution 1:[1]
You have LIKE '%"+self.buscar+"%', but I expect you wanted those %% inside the double quotes.
Also, don't construct queries as strings like this. Instead, use ? in the query and pass parameters to allow SQLite to make the substition safely:
query = "SELECT Nombre FROM Productos WHERE Nombre LIKE ? ORDER BY Nombre DESC"
self.run_query(query, (f'%{self.buscar}%',))
If you don't like f-strings for some reason:
self.run_query(query, ('%' + self.buscar + '%',))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Grismar |
