'How to pass sql primary key to dynamically generated buttons?

I've been following some tutorials on YouTube and there seems to be a bug in the code - I'm really struggling to fix the issue and it seems to be a really important thing to know how to do in tkinter (and programming in general)...

Essentially what's happening is that I'm trying to create an 'edit' button for each record in a list of records from a SQL database table. The edit button and the records are displayed iteratively as the program enumerates through the MySQL result. I then pass the ID of each record straight to the corresponding button, dynamically.

Because of this, in every enumeration of the result, the 'id_ref' variable is overwritten, meaning that by the time I come to editing the record, the ID of 'edit_button' is set to the ID of the last entry in the list.

I have tried a workaround using 'id_ref=id_ref' in the lambda function, but to no avail (it updated all records at once that way). I've also thought about maybe generating each button to be unique, but it seems like a lot of hassle and I don't know the best way to do that.

Below is the code that makes up some of the program, along with a screenshot showing me pressing the edit button and the program printing the wrong ID reference.

Result:

enter image description here

Main enumerate loop:

    mycursor.execute("SELECT * FROM talents")
    result = mycursor.fetchall()
    for index, x in enumerate(result):
        results_label = Label(results_frame, text=x[12], wraplength=140, justify='center')
        results_label.grid(row=1+index, column=0, padx=10)

        results_label = Label(results_frame, text=x[0], wraplength=140, justify='center')
        results_label.grid(row=1+index, column=1, padx=10)

        results_label = Label(results_frame, text=x[1], wraplength=140, justify='center')
        results_label.grid(row=1+index, column=2, padx=10)

        results_label = Label(results_frame, text=x[7], wraplength=140, justify='center')
        results_label.grid(row=1+index, column=3, padx=10)

        results_label = Label(results_frame, text=x[11], wraplength=140, justify='center')
        results_label.grid(row=1+index, column=4, padx=10)

        results_label = Label(results_frame, text=x[2], wraplength=140, justify='center')
        results_label.grid(row=1+index, column=5, padx=10)

        results_label = Label(results_frame, text=x[13], wraplength=140, justify='center')
        results_label.grid(row=1+index, column=6, padx=10)

        id_ref = str(x[12])
        edit_button = Button(results_frame, text='E', font=('Times New Roman', 12),
                             command=lambda: edit_record(id_ref))
        edit_button.grid(row=1+index, column=7)

        view_button = Button(results_frame, text='V', font=('Times New Roman', 12))
        view_button.grid(row=1+index, column=8)

'edit_record' function

def edit_record(id_ref):
    print(id_ref)
    winf = FormFields()
    if active_tab == 'Talent':
        winf.talents_fields()
        update_record_button = Button(winf.new_record_window, text='Update Record', command=lambda: winf.update_record(id_ref))
        update_record_button.grid(row=12, column=1, padx=10, pady=10)

'update_record' function:

    def update_record(self, talent_id):
        print(talent_id)
        sql_command = 'UPDATE Talents \
                      SET Alias = %s, Profession = %s, `Contact Number` = %s, `Email Address` = %s, Forename = %s, \
                      Surname = %s, `Address (First Line)` = %s, `Address (City)` = %s, `Post Code` = %s, \
                      `Date of Birth` = %s, `National Insurance` = %s \
        WHERE `ID` = %s'
        values = (self.alias_entry.get(),
                self.profession_entry.get(),
                self.number_entry.get(),
                self.email_entry.get(),
                self.forename_entry.get(),
                self.surname_entry.get(),
                self.first_line_address_entry.get(),
                self.city_entry.get(),
                self.postcode_entry.get(),
                self.dob_entry.get(),
                self.ni_entry.get(),
                self.id_entry.get())

        mycursor.execute(sql_command, values)
        db.commit()


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source