Мой код удаляет последний элемент в списке, а не тот, который мне нужен

#python #database #sqlite #tkinter

Вопрос:

Я хочу создать функцию, в которой пользователь получает список пользователей из базы данных и может выбрать удаление одного из них из базы данных. Это выглядит так, как я хочу, я получаю все элементы в строках с кнопкой удаления для каждого, и они называются правильно. Но функция, похоже, работает не так, как я хочу. Если я нажму любую кнопку удаления, последний пользователь будет удален. Я новичок в этом, поэтому уверен, что совершил ошибку, но не знаю где.

 def delete():
    conn = sqlite3.connect("database.db")
    c = conn.cursor()
    c.execute("DELETE FROM databasetable WHERE oid = "   str(i[5]))
    conn.commit()
    conn.close()

conn = sqlite3.connect("database.db")
c = conn.cursor()
c.execute("SELECT *, oid FROM databasetable")
listfromdatabase = c.fetchall()
conn.commit()
conn.close()

for i in listfromdatabase:
    label = Label(frameskidlararenamn, text=i[0])
    label.pack()
    button = Button(frameskidlarareknapp, text="Delete "   str(i[0]), command=delete)
    button.pack()
 

Есть какие-нибудь идеи?

Комментарии:

1. "SELECT *, oid FROM databasetable" —> "SELECT * FROM databasetable"

2. Я не уверен, что понимаю. Если я напишу «ВЫБРАТЬ * ИЗ базы данных», он не вернет идентификатор, а только созданные мной входные данные.

3. * —> Все поля таблицы

4. Вы действительно уверены, что именно так это работает в sqlite? Потому что идентификатор не возвращается, если я напишу*, но он возвращается правильно так, как я его написал. Я не думаю, что в этом проблема. Если я распечатаю список на терминале, все будет выглядеть правильно.

5. Я использую sqlite3.

Ответ №1:

В конце цикла for i in listfromdatabase: i находится последний элемент. Поэтому функция удаления удаляет этот последний элемент.

Ответ №2:

Проверьте, работает ли это, передав аргумент команде с помощью лямбда-функции.
изменилось lambda : delete(i[5]) на lambda item=i[5]: delete(item)

 button1 = [None for _ in range(len(listfromdatabase))]
for n,i in enumerate(listfromdatabase):
    label = Label(frameskidlararenamn, text=i[0])
    label.pack()
    button1[n] = Button(frameskidlarareknapp, text="Delete "   str(i[0]),command=lambda item=i[5]: delete(item))
    button1[n].pack()
 
 def delete(item):
    conn = sqlite3.connect("database.db")
    c = conn.cursor()
    c.execute("DELETE FROM databasetable WHERE oid = "   str(item))
    conn.commit()
    conn.close()
 

Просто чтобы быть уверенным, проверьте с помощью двух кнопок с одинаковым названием, но с разными функциями. Нравится

 def printnum(num):
    #print num on a label or something
button = Button(frameskidlarareknapp, text="print num 1", command=lambda: printnum(1))
button.pack()
button = Button(frameskidlarareknapp, text="print num 2", command=lambda: printnum(2))
button.pack()
 

Комментарии:

1. Спасибо вам за попытку помочь. Я попробовал это, и у меня больше нет той проблемы, которая возникла, когда я попробовал то, что написал Макс Страндберг. Но первоначальная проблема вернулась. Когда я нажимаю любую кнопку удаления, последний элемент в списке удаляется.

2. Я увидел, что написал свой первоначальный пост немного неправильно. Это не только первая кнопка удаления, которая работает. Каждая кнопка удаления работает, но все они удаляют последний элемент.

3. я чувствую, что это может быть связано с тем, что кнопка имеет одно и то же имя, возможно, требуется другое название кнопки. Обновлено 3 строки

4. Да, это звучит логично. У вас есть какие-либо идеи о том, как я должен написать свой код, чтобы дать им индивидуальное имя в зависимости от количества пользователей в базе данных?

5. Извините, что не увидел ваш обновленный код, постараюсь.

Ответ №3:

Ваше определение удаления настроено так, чтобы оно было нацелено на пятый элемент i

 def delete():
    conn = sqlite3.connect("database.db")
    c = conn.cursor()
    c.execute("DELETE FROM databasetable WHERE oid = "   str(i[5]))
    conn.commit()
    conn.close()
 

Вместо этого вы должны передать oid для удаления, изменив определение

 def delete(oid):
    conn = sqlite3.connect("database.db")
    c = conn.cursor()
    c.execute("DELETE FROM databasetable WHERE oid = "   str(oid))
    conn.commit()
    conn.close()
 

Комментарии:

1. Когда я попробовал это, я получил эту ошибку: sqlite3. Ошибка операции: рядом с «E»: синтаксическая ошибка

2. Вы также изменили определение кнопки? он должен передать правильный параметр в команду, что-то вроде command=delete(i[0]) или в зависимости от того, в каком индексе хранится ваш идентификатор, должно сработать

3. Нет, я этого не делал. Я изменил его сейчас, и это вызвало новую проблему, и я понятия не имею, почему. Теперь все пользователи удаляются без моего участия. Если я добавлю нового пользователя и снова открою окно, там будет только новый пользователь. Если я закрою окно и открою его снова, там не будет пользователей. Когда я печатаю список на терминале перед циклом for, список пуст.

4. Попробуйте сделать команду лямбда, чтобы вы определили ее как command=лямбда: удалить(i[5]). Есть вероятность, что он стреляет по нагрузке непреднамеренно

5. Смотрите мой ответ Ситцерингу, который предложил это после вашего комментария. Я попробовал и избавился от ошибки, но первоначальная проблема вернулась. Все кнопки удаления удаляют последний элемент.