#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. Смотрите мой ответ Ситцерингу, который предложил это после вашего комментария. Я попробовал и избавился от ошибки, но первоначальная проблема вернулась. Все кнопки удаления удаляют последний элемент.