@Nekech

Как исправить ошибку sqlite3.IntegrityError: UNIQUE constraint failed: users.user_id?

Не могу понять в чем ошибка
@dp.message_handler(commands=['start'])
async def start(message: types.Message):
    user_id = message.from_user.id
    user_name = message.from_user.first_name
    if not db.user_exists(message.from_user.id):
        start_command = message.text
        referrer_id = str(start_command[7:])
        if str(referrer_id) != '':
            if str(referrer_id) != str(message.from_user.id):
                db.add_user(message.from_user.id, referrer_id)
                try:
                    await bot.send_message(referrer_id,'+2 рубля')
                    #Сюда нужно будет добавить счетчик для пополнения баланса
                except:
                    pass
            else:
                db.add_user(message.from_user.id)
                await bot.send_message(message.from_user.id, "Нельзя регестрироваться по собственной ссылке")
        else:
            db.add_user((message.from_user.id))

    await message.answer(f'Бот в работе', reply_markup=kb)


async def profile(message: types.Message):
    await message.answer(f'Хмм, Юзер, вот, что у тебя есть:\nБаланс:\nКупоны для розыгрыша:\nДрузья: {db.count_reeferals(message.from_user.id)} \n',reply_markup=in1)



@dp.callback_query_handler(text='d')
async def friend(message: types.Message):
    await bot.send_message(message.from_user.id,f"Твоя ссылка:https://t.me/{BOT_NAME}?start={message.from_user.id}")
    await message.answer()

----------БД----------
import sqlite3

class Database:
    def __init__(self, db_file):
        self.connection = sqlite3.connect(db_file)
        self.cursor = self.connection.cursor()

    def user_exists(self, user_id):
        with self.connection:
            result = self.cursor.execute("SELECT * FROM 'users' WHERE 'user_id' = ?",(user_id,)).fetchall()
            return bool(len(result))

    def add_user(self, user_id, referrer_id=None):
        with self.connection:
            if referrer_id != None:
                self.cursor.execute("INSERT INTO 'users' ('user_id',''referrer_id') VALUES (?,?)", (user_id,referrer_id,))
            else:
                return self.cursor.execute("INSERT INTO 'users' ('user_id') VALUES (?)", (user_id,))

    def count_reeferals(self, user_id):
        with self.connection:
            return self.cursor.execute("SELECT COUNT('id') as count FROM 'users' WHERE 'referrer_id' = ?", (user_id,)).fetchone()[0]

Ошибка: sqlite3.IntegrityError: UNIQUE constraint failed: users.user_id
Ошибка как я понимаю вот в этой строчке
return self.cursor.execute("SELECT COUNT('id') as count FROM 'users' WHERE 'referrer_id' = ?", (user_id,)).fetchone()[0]

До нее все работало
  • Вопрос задан
  • 2447 просмотров
Пригласить эксперта
Ответы на вопрос 1
shurshur
@shurshur
Сисадмин, просто сисадмин...
Нет, эта ошибка возникает при INSERT либо UPDATE, если в результате операции в таблице users появятся две записи с одинаковым user_id. От SELECT такого быть не может. Я бы рекомендовал всё же проверить точный номер нужной строки, чтобы убедиться в этом.

Чтобы этого не происходило, нужно уметь следить за тем, чтобы пользователи второй раз не вставлялись таблицу или чтобы их id не изменялись на конфликтующие при UPDATE. Но тут, скорее всего, влияет только INSERT. Вот с ним и надо делать аккуратно, вставлять только новых пользователей, а если пользователь уже есть - ничего не делать либо обновлять имеющуюся запись (смотря как именно требуется для логики приложения).

Как вариант, можно сделать совсем по-простому: вместо INSERT использовать REPLACE, который комбинирует INSERT и UPDATE - если при вставке запись с таким id уже есть и случается ошибка, то фактически выполняется UPDATE соответствующей записи с изменением всех перечисленных полей. Например, для REPLACE INTO users (user_id, referrer_id) фактически выполнится что-то типа UPDATE users SET referrer_id=... WHERE user_id=...
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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