удаление записи из БД sqlite3 по нажатию кнопки в telegram bot на python
библиотека pyTelegramBotAPI и sqlite3. Хендлер по команде выводит все записи из базы для текущего пользователя и под каждой записью добавляет инлайн кнопку, нажатие на которую должно удалить соответствующую запись из базы. С выведением проблем нет, не могу сообразить как корректно организовать обработку нажатия на инлайн кнопку под конкретным сообщением. В моем текущем коде получается так, что DELETE FROM обращается к последнему значению цикла for и то, по какой-то причине, удаление не работает и ошибок не выдает тоже. Подскажите, плиз, в какую сторону думать.
@bot.message_handler(commands=['get'])
def get_from_my_list(message):
keyboard = types.InlineKeyboardMarkup(row_width=1)
button = types.InlineKeyboardButton("Удалить", callback_data='del')
keyboard.add(button)
with sqlite3.connect('users_data.db',check_same_thread=False) as db:
cursor = db.cursor()
user_id = message.from_user.id
query = """SELECT wish FROM wishes WHERE user_id = {}""".format(user_id)
cursor.execute(query)
data = cursor.fetchall()
for i in data:
bot.send_message(message.chat.id, i,reply_markup=keyboard)
@bot.callback_query_handler(func=lambda call: True)
def answer(call):
message = call.message
if call.data == 'del':
query = """DELETE FROM wishes WHERE wish = ?"""
cursor.execute(query,(i[0],))
send = bot.send_message(message.chat.id, 'Удалено')
Ответы (1 шт):
допустим у нас есть таблица в бд с полями:
- chat_id
- username
Функция создания клавиатуры:
def kb(chat_id):
keyboard = types.InlineKeyboardMarkup(row_width=1)
button = types.InlineKeyboardButton("Удалить", callback_data="['del', '" + str(chat_id) + "']")
keyboard.add(button)
return keyboard
здесь мы добавляем в callback_data дополнительный параметр - аргумент chat_id.
функция start:
@bot.message_handler(commands=['start'])
def start(message):
with sqlite3.connect('test.db', check_same_thread=False) as db:
cursor = db.cursor()
cursor.execute("SELECT * FROM users")
data = cursor.fetchall()
for i in data:
bot.send_message(message.chat.id, i[0], reply_markup=kb(i[0]))
и хэндлер обработки callback:
@bot.callback_query_handler(func=lambda call: True)
def callback_inline(call):
if call.data.startswith("['del'"):
print(ast.literal_eval(call.data)[1])
with sqlite3.connect('test.db', check_same_thread=False) as db:
cursor = db.cursor()
cursor.execute("DELETE FROM users WHERE chat_id = ?", (ast.literal_eval(call.data)[1],))
bot.send_message(call.message.chat.id, 'Удалено')
к call.data добавился startswith - Строка-префикс (либо кортеж строк), в наличии которой требуется удостовериться.
Таким образом, если call.data начинается с del условие будет выполнено.
используя ast.literal_eval мы можем получить дополнительные параметры переданные в call.data:
['del', '12**11'] - это обычный список, второй элемент это chat_id переданный в callback_data функции kb().
теперь мы можем передать в запрос к БД необходимое условие для удаления.