Многопоточность, mysql и телеграм бот
Пишу бота и никак не могу решить одну проблему с MySQL. Есть основная часть бота, которая отвечает за викторину, а также job_quene, который отвечает за таймер, меняет значение в БД (для каждого пользователя отдельно) и редактирует сообщение с таймером. Вместе они не могу работать и изначально создавали ошибку bytearray index out of range. Я попробовал создать два соеденения и теперь у меня бот вообще зависает при запросе к БД. Возможно ли это как-то исправить или как-то по другому сделать таймер? Код таймер
def time_controller(context):
job_cursor.execute("SELECT `time_left`,`user_id`,`time_message_id` FROM `users` WHERE `time_left` > 0")
print("1 second")
while True:
data = job_cursor.fetchone()
if (data == None):
print("No one")
break
print("One")
time_left = data[0] - 1
user_id = data[1]
message_id = data [0]
if (message_id == 0):
message_id = None
if (time_left == 0):
markup = get_start_markup()
context.bot.send_message(user_id,"Время вышло!", reply_markup=markup)
else:
try:
context.bot.edit_message_text("Осталось времени: *{0}*".format(time_left), user_id, data[2], parse_mode="Markdown")
except Exception as e:
print(e)
job_cursor.execute("UPDATE `users` SET `time_left` = {0}".format(time_left))
#jobdb.commit()
Код функции, отвечающей за викторину:
def Victorine(update, context): # функция, обрабатывающая викторину
user_id = update.message.from_user.id
cursor.execute("SELECT `user_id` FROM `users` WHERE `users`.`user_id` = {0} AND time_left > 0".format(user_id))
is_game_started = cursor.fetchone()
if (is_game_started == None): # Если пользователь только запустил викторину, то идёт эта функция
cursor.execute("SELECT `data` FROM `questions` WHERE `number` = 1 AND type = 1")
result = cursor.fetchone()
if (result == None): # Если админ ещё не сделал/запустил викторину, то отправляеться это сообщеник
context.bot.send_message(user_id, "К сожалению, сейчас нет никаких викторин. Приходите позже")
return
context.bot.send_message(user_id, "Игра началась!")
message_id = context.bot.send_message(user_id, "Осталось времени: *{}*".format(120), parse_mode="Markdown").message_id
cursor.execute("UPDATE `users` SET `time_left` = '20', `question_number` = '1',`time_message_id` = {1} WHERE `users`.`user_id` = {0} ".format(user_id, message_id))
first_question = get_question_data(user_id)
context.bot.send_message(user_id, first_question["text"], reply_markup=first_question["markup"])
else: # Если продолжаеться викторина
question_number = get_guestion_number(user_id) # Получаем номер вопросв
otvet = check_data(update.message.text) # Обрабатываем данные
cursor.execute("SELECT `data` FROM `questions` WHERE `number` = {num} AND type = 0 AND data = '{otv}' AND is_right_answer = 1".format(num=question_number, otv=otvet))
result = cursor.fetchone()
if (result == None): # Правильный/Неправильный вариант
context.bot.send_message(user_id, "Неправильно! Может в следующий раз повезёт :)")
else:
context.bot.send_message(user_id, "Правильно! Сегодня твой день! :)")
cursor.execute("UPDATE `users` SET `question_number` = '{0}' WHERE `users`.`user_id` = {1} ".format(question_number + 1,user_id))
is_sended = get_question_data(user_id)
if (is_sended == None): # Если вопросы закончились, то отправляем сообщение и выходим
markup = get_start_markup()
cursor.execute("UPDATE `users` SET `question_number` = 0,`time_left` = 0,`time_message_id` = 0 WHERE `users`.`user_id` = {0} ".format(user_id))
context.bot.send_message(user_id,"Поздравляю! Вопросы закончились", reply_markup=markup)
return
# Если нет, то продолжаем задавать вопросы
cursor.execute("SELECT `time_left` FROM `users` WHERE `user_id` = {0}".format(user_id))
time_left = cursor.fetchone()[0]
message_id = context.bot.send_message(user_id, "Осталось времени: *{0}*".format(time_left), parse_mode="Markdown").message_id
cursor.execute("UPDATE `users` SET `time_message_id` = {1} WHERE `users`.`user_id` = {0} ".format(user_id, message_id))
context.bot.send_message(user_id, is_sended["text"], reply_markup=is_sended["markup"])
mydb.commit() # Сохраняем значения в БД
А также определение БД:
mydb = mysql.connector.connect(
host="localhost",
user="bot",
passwd="123",
database="bot"
)
jobdb = mysql.connector.connect(
host="localhost",
user="bot",
passwd="123",
database="bot"
)
cursor = mydb.cursor()
job_cursor = jobdb.cursor()
Ответы (1 шт):
У меня получилось исправить проблему с помощью MySQL pooling. Статья: https://pynative.com/python-database-connection-pooling-with-mysql/