@hey_umbrella

Как прибавить +1 к значению в sqlite?

Мне нужно,чтобы после нажатия на кнопку к star прибавляло +1,в чем ошибка?
if call.data == 'stars':
            #ursor.execute(f'UPDATE stars SET star = star + 1 WHERE photo = "{photo}"')
            #con.commit()
            photo = call.message.text
            con = sqlite3.connect("database.db")
            cursor = con.cursor()
            cursor.execute(f'SELECT star FROM stars WHERE photo = "{photo}"')
            star = cursor.fetchone()[0]
            con.commit()
            cursor.execute(f'UPDATE stars SET star = star +1; WHERE photo = "{photo}"')
            con.commit()
            markup = telebot.types.InlineKeyboardMarkup()
            markup.add(telebot.types.InlineKeyboardButton(text=f'Рейтинг - ⭐{star}', callback_data="stars"))


Сама ошибка - star = cursor.fetchone()[0]
TypeError: 'NoneType' object is not subscriptable
  • Вопрос задан
  • 131 просмотр
Решения вопроса 1
@Vindicar
> Сама ошибка - star = cursor.fetchone()[0]
> TypeError: 'NoneType' object is not subscriptable

not subscriptable означает что ты пытаешься взять индекс у объекта, который это не поддерживает. В твоем случае объект типа NoneType - т.е. None.
Иными словами, cursor.fetchone() вернул None, и конечно у None нельзя взять индекс.
Почему fetchone() вернул None? Потому что запрос SELECT не нашёл ни одной строки с подходящим значением photo!

Как это решить?
Вставить в таблицу строку с photo, а если не получится (так как такое photo уже есть), то обновить. Есть два способа.
1. Кодом. Проверить, что вернул fetchone(). Если None, то делаем INSERT. Если не None, то UPDATE.
2. Средствами БД, что обычно называется UPDATE/INSERT, или коротко UPSERT. Для sqlite это потребует примерно такого запроса:
INSERT INTO stars (photo, star) VALUES (ид фото, 1) ON CONFLICT (photo) DO UPDATE SET star = star + 1

Требование: столбец photo должен быть первичным ключом или хотя бы иметь уникальный индекс, иначе запрос просто будет добавлять дубликат строки.

ВАЖНО
f'SELECT star FROM stars WHERE photo = "{photo}"' - никогда так не делайте! Особенно если входные данные получены от пользователя. Это хороший способ заполучить SQL-инъекцию.
Используйте placeholders, по порядку:
cursor.execute('SELECT star FROM stars WHERE photo = ?', (photo, ) )
или по именам
cursor.execute('SELECT star FROM stars WHERE photo = :photo', {'photo' : photo} )
И удобнее и безопаснее.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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