@uni_sad_corn

Как решить проблему с выбором только что созданных записей в БД?

У меня есть Телеграмм бот, выполняющий функции to-do-шника, который использует API, работающую на Laravel. У API есть множество методов, в том числе добавление и редактирование записей. В некоторых функциях бота предусмотрен механизм выбора записей(Например, при создании подзадачи нужно выбрать задачу, к которой она будет привязана).
Суть проблемы:
Если создать запись, а потом попробовать выбрать ее в качестве родительской при создании другой записи, то бот уходит в краш и я совершенно не понимаю, в чем дело. Ниже прилагаю материалы и очень надеюсь на вашу скорейшую помощь, так как скоро защита диплома xD
P.S. За код сильно не пинайте, учусь только)

Код Функций бота (создание подзадачи):
1. В цикле for выводятся задачи, которые пользователь может выбрать как родительские
markup = types.ReplyKeyboardMarkup(one_time_keyboard=True)

username = '@' + message.from_user.username
sql = "SELECT id FROM users WHERE tg_name = '{}'".format(username)
db.execute(sql)
user_id = db.fetchone()
user = user_id[0]

url = 'http://intask/public/api/tasks/{}'.format(user)
result = requests.get(url)
tasks = result.json()

for task in tasks['tasks']:
    markup.add(task['name'])

msg = bot.reply_to(message, 'Выберите задачу', reply_markup=markup)
bot.register_next_step_handler(msg, next_create_subtask_step)


2. Непосредственно функция создания подзадачи
Вот в этом моменте - task = task_id[0] - происходит краш(скриншоты ошибок прикреплю позже)
def next_create_subtask_step(message):
    name_task = message.text
    sqlb = "SELECT id FROM tasks WHERE name = '{}'".format(name_task)
    db.execute(sqlb)
    task_id = db.fetchone() 
    task = task_id[0]

    bot.reply_to(message, 'Придумайте название подзадачи')
    @bot.message_handler(content_types='text')
    def request_subtask(message):
        subtask = {"name": message.text, "id_task": task}
        payload = subtask
        result = requests.post('http://intask/public/api/subtask', json=payload)
        json = result.json()
        
        bot.reply_to(message, 'Спасибо, ожидайте')

        resp = '<b>Ваша созданная подзадача:</b>\n\n'
        resp += '{}\n'.format(json['subtask']['name'])
        resp += 'Задача: {}\n'.format(json['subtask']['task'])
        resp += 'Автор задачи: {}\n'.format(json['subtask']['autor'])
        bot.send_message(message.chat.id, resp, parse_mode="HTML")
        message.text = "Задачи"
        process_menu_step(message)


Функции API:
1. getAllTasks($user_id) - доступна по роуту - http://intask/public/api/tasks/{id_user} /GET Method
try {
            $assigned = \App\Models\Assigned::where('id_user', $id)->get(); #Auth::user()->id
            $tasks = [];
            $i = 0;
            foreach($assigned as $as){
                $item = \App\Models\Task::find($as->id_task); #Potential need add where('complete_flag', 0)
                $tasks[$i] = $item;
                $tasks[$i]["id_autor"] = $item->User()->get()[0]->tg_name;
                $i++;
            }
            $buf = [];
            foreach($tasks as $task){
                $buf[$task->Board()->get()[0]->name][] = $task->name;
            }
            $data = [];
            $data['tasks'] = $tasks;
            $data['boards'] = $buf;
            return response()->json($data, 200);
        } catch (Throwable $th) {
            $data = [];
            $data[] = ['response' => 'Something went wrong'];
            $data[] = ['error' => $th];
            return response()->json($data, 400);
        }


2. createSubTask(Request $req) - доступна по роуту - intask/public/api/subtask /POST Method
try {
            $subtask = new \App\Models\SubTask;
            $subtask->name = $req->name;
            $subtask->save();

            $middle = new \App\Models\Sub_in_Task;
            $middle->id_subtask = $subtask->id;
            $middle->id_task = $req->id_task;
            $middle->save();

            $data = [];
            $data['subtask'] = $subtask;
            $task = \App\Models\Task::find($req->id_task);
            $data['subtask']['task'] = $task->name;
            $data['subtask']['autor'] = $task->User()->get()[0]->tg_name;
            return response()->json($data, 201);
        } catch (\Throwable $th) {
            $data = [];
            $data[] = ['response' => 'Something went wrong'];
            $data[] = ['error' => $th];
            return response()->json($data, 400);
        }

UPD. Ошибка в консоли:
Traceback (most recent call last):
  File "c:\Users\Emaq-\Desktop\inTaskBot\bot.py", line 702, in <module>
    bot.polling(none_stop=True)
  File "C:\Users\Emaq-\Desktop\inTaskBot\env\Lib\site-packages\telebot\__init__.py", line 1043, in polling
    self.__threaded_polling(non_stop=non_stop, interval=interval, timeout=timeout, long_polling_timeout=long_polling_timeout,
  File "C:\Users\Emaq-\Desktop\inTaskBot\env\Lib\site-packages\telebot\__init__.py", line 1118, in __threaded_polling
    raise e
  File "C:\Users\Emaq-\Desktop\inTaskBot\env\Lib\site-packages\telebot\__init__.py", line 1074, in __threaded_polling
    self.worker_pool.raise_exceptions()
  File "C:\Users\Emaq-\Desktop\inTaskBot\env\Lib\site-packages\telebot\util.py", line 147, in raise_exceptions
    raise self.exception_info
  File "C:\Users\Emaq-\Desktop\inTaskBot\env\Lib\site-packages\telebot\util.py", line 90, in run
    task(*args, **kwargs)
  File "c:\Users\Emaq-\Desktop\inTaskBot\bot.py", line 464, in next_create_subtask_step
    task = task_id[0]
           ~~~~~~~^^^
TypeError: 'NoneType' object is not subscriptable

UPD #2. Только что обнаружил, что если попробовать выбрать задачу после запуска бота, после ошибки, то все отрабатывает как надо, надеюсь, это как-то поможет
  • Вопрос задан
  • 162 просмотра
Решения вопроса 1
@uni_sad_corn Автор вопроса
И так, проблема была решена перекладыванием обязанности доставать из БД записи с бота на API полностью. Это сработало, хотя до сих пор не понятно, что при первом варианте подхода было не так
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы