Как проверить есть ли id пользователя в базе данных sqlite используя телеграм бота в python?
Я написал телеграм бота, в котором при нажатии на кнопку "My account" id пользователя должен сверяться с базой данных и если пользователь есть в базе данных то бот напишет "bd check" если пользователя нет то напишет "bd netu"
Но проблема в том что, когда я пытаюсь проверить через data1 = cur.fetchall() и пишу if message.chat.id in data1 то условие выполняется некорректно, оно не сравнивает нормально, возможно из за того что в data1 id сохраняется как (id,), а message.chat.id = id .
Я пробовал даже добавлять эти лишние "(" ")" "," но условие все равно не работает правильно. Работает только условие elif "bd netu".
Вот мой код
def phone(message):
keyboard = types.ReplyKeyboardMarkup(row_width=2, resize_keyboard=True)
button_phone = types.KeyboardButton(text="Send contact", request_contact=True)
akkount = types.KeyboardButton(text="My account?")
keyboard.add(button_phone)
keyboard.add(akkount)
chat_id = message.chat.id
bot.send_message(message.chat.id, "Спасибо", reply_markup=keyboard)
# bot.send_message(message.chat.id, "Hello World!", reply_markup=bazar)
# a = "("
# f = ",)"
# b = str(chat_id)
# c = a + b + f
# print(c)
@bot.message_handler(content_types=['text'])
def handler(message):
if message.text == "My account?":
with sq.connect("bot5.db") as con:
cur = con.cursor()
data1=cur.execute("SELECT id FROM info1")
con.commit()
rop = []
data1 = cur.fetchall()
rop.append(data1)
chat_id = message.chat.id
a = "("
f = ",)"
b = str(chat_id)
c = a + b + f
print(c)
print(data1)
# print(*data1)
# print(rop)
print(message.chat.id)
if c in data1:
bot.send_message(message.chat.id, "Bd check")
elif c not in data1:
bot.send_message(message.chat.id, "Bd netu")
Ответы (1 шт):
Пример решения:
cur = con.cursor()
chat_id = message.chat.id
exists = cur.execute("SELECT 1 FROM info1 WHERE id = ?", [chat_id]).fetchone()
text = "Bd check" if exists else "Bd netu"
bot.send_message(chat_id, text)
Если любопытно как и почему, то посмотрите ниже :)
Описание решения:
- Используем поиск через базу данных, передавая
chat_idв запрос, если что-то есть, то вернется1 - Используем метод
fetchone, т.к. интересует только первое значение. Если с такимidв таблицеinfo1что-то будет, то вернется кортеж(1,), иначеNone(это важно для проверки наличия записей в коде, т.к. кортеж на один элемент при проверках будет считатьсяTrue, аNoneкакFalse) - Не формируем вручную строку запроса с значениями, используем binding-параметры, они помечаются как
?(для расширения темы гуглим про sql-инъекции). В примере для передачи параметров использовал список, но можно и кортежcur.execute("SELECT 1 FROM info1 WHERE id = ?", (chat_id,)), но, по-мне, он не такой выразительный, как список, особенно, когда параметр один
Заметил следующие проблемы в коде:
SELECTбез самого условия, что приводит к проверке в коде. А если у вас будет миллион пользователей? :)- Коммит на
SELECT. Это не нужно, т.к. ничего в базе не менялось - Неумелая работа с данными python. Метод
fetchallвернул список из кортежей, в кортежах находится то, что вSELECTуказывали, поэтому построение из этого строки ошибка. Решением такого может быть пробег по списку кортежей и поиск нужного, типа:exists = any(x[0] == chat_id for x in data1). Далее, проверить чтоif exists: ... else: ..., можно и в одну строку:bot.send_message(message.chat.id, "Bd check" if exists else "Bd netu") - Условие имеет двойную проверку, достаточно
if ...: else, ведь еслиif c in data1:будетFalse, тоelif c not in data1:точно будетTrue

