着色剂/SQLite3:根据特定输入字段筛选表数据的GUI

z9smfwbn  于 2023-01-05  发布在  SQLite
关注(0)|答案(1)|浏览(111)

我正在尝试创建一个基于用户输入的Tkinter GUI,它将遍历一个表,并选择符合条件的行,这些行只与已输入内容的输入字段相匹配。
例如,假设我们有一个名为pets的表,其中包含列nameagespecies

+------------------+-----------+-----------+
 | name             | age       | species   |
 +------------------+-----------+-----------+
 | Muffin           | 3         | Cat       |
 | Dash             | 8         | Dog       |
 | Winnie           | 10        | Cat       |
 | Chewie           | 1         | Hamster   |
 | Slinky           | 3         | Snake     |
 +------------------+-----------+-----------+

我有一个Tkinter应用程序,用户输入他们想要过滤的标准:

from tkinter import *
import tkinter as tk
import sqlite3

def main():

    def do_something():
        connection = sqlite3.connect("my_database.db")
        cursor = connection.cursor()

        name = name_str.get()
        age = age_str.get()
        species = species_str.get()

        cursor.execute("SELECT * FROM pets WHERE name=? AND age=? AND species=? ", (name, age, species))
        pet = cursor.fetchall()

        for row in pet:
            print(row)
    
    root = tk.Tk()

    name_str = StringVar()
    age_str = StringVar()
    species_str = StringVar()

    frame = Frame(root, padx=20, pady=20)
    frame.pack()

    name_label = Label(frame, text="Name").pack()
    name_entry = Entry(frame, textvariable=name_str).pack()

    age_label = Label(frame, text="Age").pack()
    age_entry = Entry(frame, textvariable=age_str).pack()

    species_label = Label(frame, text="Species").pack()
    species_entry = Entry(frame, textvariable=species_str).pack()

    filter_button = Button(frame, text="Filter", command=do_something).pack()

    mainloop()

main()

如果我想找到表中年龄为10的所有Cats,我会在Age字段中键入10,在Species字段中键入Cat,使用SELECT语句,我希望打印出符合该条件的宠物(表中唯一的宠物是Winnie)
但是,因为我没有在Name字段中提供条目,所以没有从表中检索到任何内容(我假设这是因为StringVar()在没有输入任何内容时变成了NoneType,所以函数要查找name=None
实现这个过滤系统的最佳方式是什么?它允许我根据我使用的输入字段来搜索表?有没有更好的方式来格式化我的SELECT语句,让我可以这样做?或者我必须使用Python代码创建一个逻辑函数?
我尝试过使用if语句来检查字段中是否有条目,然后再继续,有两种尝试过滤数据的方法。
第一个是包含要搜索的列的列表,如果在任何字段中检测到条目,它会将SQL列名添加到名为args = []的列表中。
首次尝试:

args = []

if len(name) == 0:
    pass
else:
    args.append("name=?")

if len(age) == 0:
    pass
else:
    args.append("age=?")

if len(species) == 0:
    pass
else:
    args.append("species=?")

cursor.execute("SELECT * FROM pets WHERE {}").format(args)

我尝试过的第二种方法是,如果if语句检测到字段中的一个条目,它将选择与用户输入匹配的所有行,并将其添加到列表中,然后转到下一个if语句,希望我可以按索引将数据拆分为单独的字符串,但它并没有像我期望的那样工作。
第二次尝试:

if len(name) == 0:
    pass
else:
    cursor.execute("SELECT name FROM pets WHERE name=?", [name])
    name_data = cursor.fetchall()
            
    name_list = []
            
    for row in name_data:
        name_list.append(row)

if len(age) == 0:
    pass
else:
    cursor.execute("SELECT age FROM pets WHERE age=?", [age])
    age_data = cursor.fetchall()
            
    age_list = []
            
    for row in age_data:
        age.append(row)

if len(species) == 0:
    pass
else:
    cursor.execute("SELECT species FROM pets WHERE species=?", [species])
    species_data = cursor.fetchall()
            
    species_list = []
            
    for row in species_data:
        species.append(row)
chhqkbe1

chhqkbe11#

您需要动态构建SQL:

def do_something():
    connection = sqlite3.connect("my_database.db")
    cursor = connection.cursor()

    name = name_str.get().strip()
    age = age_str.get().strip()
    species = species_str.get().strip()

    conditions = []
    args = []
    if name:
        conditions.append('name = ?')
        args.append(name)
    if age:
        conditions.append('age = ?')
        args.append(age)
    if species:
        conditions.append('species = ?')
        args.append(species)

    # default select all if no condition is given
    sql = "SELECT * FROM pets"
    if conditions:
        # add the WHERE clause if any condition is given
        sql += " WHERE "+" AND ".join(conditions)

    cursor.execute(sql, args)
    pets = cursor.fetchall()

    if pets:
        for pet in pets:
            print(pet)
    else:
        print('No pet found')

相关问题