Python Forum
[Tkinter] Database with gui
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Database with gui
#9
It took me a while to figure out how to do the SELECT using only non-empty fields, and the result is a little dense. But it is far simpler than trying to do it any other way I could think of.
def find_all():
    """Find records that match all non-empty fields"""
    args = [f'{n}="{v.get()}"' for n, v in zip(field_names, fields) if v.get() != '']
    if len(args) > 0:
        search('SELECT * FROM routine WHERE ' + ' AND '.join(args))
The list comprehension makes a list of strings that look like this:
args = ['Date="June 5"', 'Study="History"']
The construction of the field name="value" strings is done by this part:
f'{n}="{v.get()}"'
f' is the new f string way of formatting strings in Python. Curly brackets {} surround expressions that are evaluted and converted to strings. This could be rewritten as:
n+'="'+v.get()+'"'
This part passes n and v values to the string constructor part.
for n, v in zip(field_names, fields) if v.get() != ''
field_names is a list of strings, the same strings used as field names for the records in the database. There's probably a way to get this info from the database, but this is my first sqlite3 program and I did not find how to do that yet.

fields are StringVar's that are bound to the Entry widgets in the GUI. The Entry's are used to enter/view the field values for a database record.
for n, v in zip(field_names, fields)
This part zips together values from the field_names and fields lists. If you have two lists letters = ['A', 'B', 'C', 'D'] and numbers[1, 2, 3, 4]. zip(letters, numbers) would generate tuples ('A', 1), ('B', 2), ('C', 3) and ('D', 4). This is a really easy way to combine two lists and shorter than using a loop.
pairs = []
for i in range(len(letters)):
    pairs.append((letters[i], numbers[i]))
This last part pares down the args list to only contain entries where the field value is not ''.
if v.get() != ''
The result of the comprehension is a list of field="value" strings for each non-empty field. Now I need to put these strings together separated by ' AND ' or ' OR '. That is surprisingly tricky to do using loops, but really simple using str.join().
' AND '.join(args)
If args = ['Date="June 5"', 'Study="History"'], this would produce args = 'Date="June 5" AND Study="History"'. If args = ['Date="June 5"'], join() is smart enough to not use the joining string and returns 'Date="June 5"'

The final step is to put the SELECT command part together with the args part.
search('SELECT * FROM routine WHERE ' + ' AND '.join(args))
Using the args from previous examples this is the same as:
search('SELECT * FROM routine WHERE ' + 'Date="June 5" AND Study="History"')
or
search('SELECT * FROM routine WHERE Date="June 5" AND Study="History"')
Reply


Messages In This Thread
Database with gui - by mark9 - Mar-19-2021, 08:26 PM
RE: Database with gui - by deanhystad - Mar-20-2021, 02:23 PM
RE: Database with gui - by mark9 - Mar-20-2021, 04:32 PM
RE: Database with gui - by deanhystad - Mar-20-2021, 05:23 PM
RE: Database with gui - by mark9 - Mar-21-2021, 09:33 AM
RE: Database with gui - by deanhystad - Mar-22-2021, 02:55 AM
RE: Database with gui - by mark9 - Mar-22-2021, 12:03 PM
RE: Database with gui - by deanhystad - Mar-21-2021, 09:30 PM
RE: Database with gui - by deanhystad - Mar-22-2021, 02:44 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020