Я только начинаю свой путь в программировании и уже долгое время стараюсь разобраться с одной ошибкой. <br/> Я разрабатываю бота на Python, используя библиотеки sqlite и telebot. <br/> <pre><code class="python">import telebot, sqlite3 from telebot import types conn = sqlite3.connect('users.db', check_same_thread=False) cursor = conn.cursor() # Создание таблицы trial cursor.execute('''CREATE TABLE IF NOT EXISTS trial (id INTEGER PRIMARY KEY, trialkey TEXT, trialactive INTEGER)''') conn.commit() # Создание таблицы users cursor.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, chat_id INTEGER, subscribed INTEGER, user_id INTEGER UNIQUE, username TEXT, torch INTEGER, trial INTEGER)''') conn.commit() @bot.message_handler(commands=['trial']) def trial_handler(message): if list(cursor.execute(f'SELECT EXISTS (SELECT * FROM users WHERE trial = 1 AND chat_id = {message.chat.id})').fetchall()[0])[0] == 1: bot.send_message(message.chat.id, "Вам доступен бесплатный пробный период в 3 дня") cursor.execute('SELECT trialkey FROM trial WHERE trialactive = 1 LIMIT 1') results = cursor.fetchall() bot.send_message(message.chat.id, "Ваш ключ:") bot.send_message(message.chat.id, text = results) cursor.execute(f'UPDATE trial SET trialactive = 0 WHERE trialkey = {results}') conn.commit() else: bot.send_message(message.chat.id, "Вы использовали пробную версию.\n\nЕсли Вы желаете воспользоваться функциями VPN сервиса, оплатите подписку через ")</code></pre> <br/> <br/> Команда должна работать следующим образом: она проверяет, может ли пользователь использовать пробную подписку, и если может, предоставляет ее, извлекая из другой таблицы, где эта информация хранится. <br/> <br/> Можете подсказать, в чем может быть проблема?
Ошибка `sqlite3.OperationalError: no such column` обычно возникает, когда вы пытаетесь обратиться к колонке, которой нет в вашей таблице. Это может произойти по нескольким причинам. Давайте рассмотрим ваш код и возможные причины появления этой ошибки. ### Возможные причины и решения: 1. **Ошибка в названии колонки**: Убедитесь, что названия колонок в запросах точно соответствуют таким, как они определены в вашей таблице. 2. **Обновление схемы базы данных**: Если вы изменили структуру таблицы, возможно, это не было отражено в вашей базе данных. Убедитесь, что таблицы были созданы правильно. Вы можете удалить файл `users.db` и пересоздать его, чтобы убедиться, что структура базы данных соответствует вашему коду. 3. **Использование переменных**: В вашем коде, последняя строка в функции `trial_handler` использует `results` как переменную, которая, вероятно, является списком. Вместо этого вы должны передать конкретный элемент списка (например, `results[0][0]`), иначе SQLite попытается найти колонку с именем `results`, что приведет к ошибке. ### Обновленный код в функции `trial_handler`: ```python @bot.message_handler(commands=['trial']) def trial_handler(message): if list(cursor.execute(f'SELECT EXISTS (SELECT * FROM users WHERE trial = 1 AND chat_id = {message.chat.id})').fetchall()[0])[0] == 1: bot.send_message(message.chat.id, "Вам доступен бесплатный пробный период в 3 дня") cursor.execute('SELECT trialkey FROM trial WHERE trialactive = 1 LIMIT 1') results = cursor.fetchall() if results: # Проверка, есть ли результаты trial_key = results[0][0] # Извлечение ключа из списка bot.send_message(message.chat.id, f"Ваш ключ: {trial_key}") # Обновляем значение trialactive в таблице trial cursor.execute('UPDATE trial SET trialactive = 0 WHERE trialkey = ?', (trial_key,)) conn.commit() else: bot.send_message(message.chat.id, "Ключ для пробного периода не найден.") else: bot.send_message(message.chat.id, "Вы использовали пробную версию.\n\nЕсли Вы желаете воспользоваться функциями VPN сервиса, оплатите подписку через ") ``` ### Что изменилось: - Вставлена проверка `if results:` для того, чтобы убедиться, что запрос вернул ключ. - Вместо прямого использования `results` в запросе `UPDATE`, используется `trial_key` с правильным индексированием и параметризированным запросом (используется `?` вместо форматирования строк, это помогает избежать SQL-инъекций). ### Общие советы: - Регулярно проверяйте вашу базу данных, чтобы удостовериться, что структура таблиц соответствует вашим ожиданиям. - Также рекомендуется использовать логирование или отладку, чтобы отслеживать значения переменных и ошибки. Пожалуйста, попробуйте указанные изменения и посмотрите, устранена ли ошибка.
Я очень зеленый в программировании, не знаю какой час сижу и разбираю одну ошибку.ну почему ты даже доки не пытаетесь для начала почитать? https://docs.python.org/3/library/sqlite3.html#sql...
Объясняю на пальцах:
- обновить запись, где столбецUPDATE trial SET trialactive = 0 WHERE trialkey = 'vless:-test'
trialkey
равен строке "vless:-test"
- обновить запись, где столбецUPDATE trial SET trialactive = 0 WHERE trialkey = vless:-test
trialkey
равен столбцуvless:-test
, а такого столбца у тебя нет.
А причина - потому что ты не озаботился как следует посмотреть примеры работы с БД в питоне, и сразу побежал херачить текст запроса с помощью f-строк, хотя каждый первый туториал предупреждает что так делать нельзя, а нужно использовать placeholder'ы.
Ссылку на https://docs.python.org/3/library/sqlite3.html#sql... тебе выше дали, разобрать её несложно.
Первый пример кода (который помечен# Never do this -- insecure!
) допускает ту же самую ошибку, что и твоёи другие запросы.cursor.execute(f'UPDATE trial SET trialactive = 0 WHERE trialkey = {results}')
А второй пример кода показывает, как правильно.
# This is the qmark style used in a SELECT query: params = (1972,) cur.execute("SELECT * FROM lang WHERE first_appeared = ?", params)
Т.е. ставишь знак вопроса там, где нужно вставить значение, а потом вторым параметром передаёшь кортеж вставляемых значений - столько, сколько у тебя знаков вопроса в запросе.