繁体   English   中英

PYTHON SQLITE 选择可能存在或不存在的多个 where 条件

[英]PYTHON SQLITE selecting multiple where conditions that may or may not exist

处理一些使用 pysimplegui 作为 UI 和 SQlite 进行数据排序的代码。 我正在使用 SQLite 的执行函数根据用户在 UI 中通过变量输入的数据来选择数据。 例如,用户想要搜索零件名称,他们在框中输入全部或部分名称,点击搜索按钮,然后运行我的“parts_search”方法,然后仅根据零件名称过滤结果。 或者用户在多个框中输入信息,然后根据具有信息的框进行过滤。

这是可运行的代码,前提是您将文件base1.db添加到与脚本本身相同的文件夹位置

import PySimpleGUI as sg
import os.path
import sqlite3

# sql var
c = None
conn = None
setup = None

# list var
parts = []


def sql():
    global setup
    conn_sql()
    c.execute("""CREATE TABLE IF NOT EXISTS parts (part_name TEXT, part_number TEXT, part_series TEXT, 
    part_size INTEGER, job_type TEXT)""")
    conn.commit()
    if conn:
        conn.close()


def conn_sql():
    global c
    global conn

    # SQL connection var
    if os.path.isfile('./base1.db'):
        conn = sqlite3.connect('base1.db')
        c = conn.cursor()


def main_gui_parts():
    global parts

    layout = [[sg.Text('Part Name:  '), sg.Input(size=(20, 1), key='-PName-'), sg.Text('Part Series:'),
                  sg.Input(size=(10, 1), key='-PSeries-')],
                 [sg.Text('Part Number:'), sg.Input(size=(20, 1), key='-PNumber-'), sg.Text('Part Size:'),
                  sg.Input(size=(10, 1), key='-PSize-')],
                 [sg.Checkbox('Fit', key='-PFit-'), sg.Checkbox('Weld', key='-PWeld-'),
                  sg.Checkbox('Assemble', key='-PAssemble-'),
                  sg.Button('Search', key='-PSearch-')],
                 [sg.Listbox(parts, size=(58, 10), key='-PParts-')], [sg.Button('Back', key='-PBack-')]]

    window = sg.Window('parts list', layout, grab_anywhere=True)

    sql()

    while True:
        event, values = window.read()

        if event == 'Close' or event == sg.WIN_CLOSED:
            break

        # PART WINDOW
        part_name = values['-PName-']
        part_series = values['-PSeries-']
        part_number = values['-PNumber-']
        part_size = values['-PSize-']
        fit = values['-PFit-']
        weld = values['-PWeld-']
        assemble = values['-PAssemble-']
        if event == '-PSearch-':
            print('search parts')
            part_search(part_name, part_series, part_number, part_size, fit, weld, assemble)
        if event == '-PBack-':
            break

    window.close()


def part_search(part_name, part_series, part_number, part_size, fit, weld, assemble):
    global parts
    conn_sql()
    filter_original = """SELECT * FROM parts WHERE """
    filter = filter_original
    if part_name:
        print('part name: ' + part_name)
        if filter == filter_original:
            filter += """part_name LIKE ? """
        else:
            filter += """AND part_name LIKE ? """
    if part_series:
        print('part series: ' + part_series)
        if filter == filter_original:
            filter += """part_series=(?) """
        else:
            filter += """AND part_series=(?) """
    if part_number:
        print('part number: ' + part_number)
        if filter == filter_original:
            filter += """part_number LIKE ? """ ### DONT USE LIKE???
        else:
            filter += """AND part_number LIKE ? """  ### DONT USE LIKE???
    if part_size:
        print('part size: ' + part_size)
        if filter == filter_original:
            filter += """part_size=(?) """
        else:
            filter += """AND part_size=(?) """
    if fit:
        print('job type: ' + str(fit))
        if filter == filter_original:
            filter += """job_type = fit """
        else:
            filter += """AND job_type = fit """
    if weld:
        print('job type: ' + str(weld))
        if filter == filter_original:
            filter += """job_type = weld """
        else:
            filter += """AND job_type = weld """
    if assemble:
        print('job type: ' + str(assemble))
        if filter == filter_original:
            filter += """job_type = assemble"""
        else:
            filter += """AND job_type = assemble"""
    print(filter)
    #if filter != filter_original:
        #c.execute(filter, ())
    #else:
        #c.execute("""SELECT * FROM parts""")


main_gui_parts()

问题:底部的注释代码是我无法弄清楚的地方(在“part_search”方法中)。 我不会一直使用所有变量。 仅使用用户提供的变量进行过滤。 这意味着元组应该只包含用户输入的变量。

如果使用了所有变量,这就是它的样子。 c.execute(filter, (part_name, part_series, part_number, part_size, fit, weld, assemble))但更常见的是,其中一些变量将被使用,并且可能需要看起来像这样。 c.execute(filter, (part_name, part_series, weld))不知何故我需要这里的变量是可删除的(因为没有更好的词)

我一直在学习很多关于 SQLite 的知识,但我可能会看到隧道视野,并且想不出另一种方法来解决这个问题。

可能最简单的处理方法是将所有过滤条件和值放入列表中,然后仅在过滤器列表的长度不为零时添加WHERE子句。 例如:

query = """SELECT * FROM parts"""
filters = []
values = []
if part_name:
    filters.append("""part_name LIKE ?""")
    values.append(part_name)
...
if len(filters):
    query += ' WHERE ' + ' AND '.join(filters)
c.execute(query, tuple(values))

注意:如果您的过滤器包含OR条件,则需要在构建查询时将它们括起来以确保正确操作,即

query += ' WHERE (' + ') AND ('.join(filters) + ')'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM