@Matveyyyy

Почему выводит ошибку(sqlite3)?

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:
                return 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,))

ошибка:
File "C:\Users\matvey\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 415, in _process_polling_updates
    for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\matvey\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 235, in process_updates
    return await asyncio.gather(*tasks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\matvey\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\handler.py", line 117, in notify
    response = await handler_obj.handler(*args, **partial_data)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\matvey\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 256, in process_update
    return await self.message_handlers.notify(update.message)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\matvey\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\handler.py", line 117, in notify
    response = await handler_obj.handler(*args, **partial_data)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\matvey\Documents\@rollscum\main.py", line 66, in start
    db.add_user(message.from_user.id, referrer_id=None)
  File "c:\Users\matvey\Documents\@rollscum\db.py", line 18, in add_user
    return self.cursor.execute("INSERT INTO 'users' ('user_id') VALUES (?)", (user_id,))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.IntegrityError: UNIQUE constraint failed: users.user_id
  • Вопрос задан
  • 151 просмотр
Пригласить эксперта
Ответы на вопрос 1
Frostealth
@Frostealth
Backend Developer
Потому что происходит попытка добавить пользователя с `user_id`, который уже существует.
В таблице уже есть пользователь с таким `user_id`, и БД выдает ошибку об этом, т.к. стоит ограничение о том, что `user_id` должен быть уникальным, без дублей.

Добавьте AUTOINCREMENT для `user_id` в таблице и не указывайте `user_id` при добавлении нового пользователя. В таком случае БД будет сама выставлять числовой идентификатор для новых юзеров.
Другой вариант - это использовать uuid4 или ему подобные для генерации случайного идентификатора на стороне приложения.

Предлагаю почитать: https://metanit.com/sql/sqlite/2.3.php

В случае, если данные юзеров, в т.ч. и идентификаторы, приходят из одного внешнего источника (например из телеграма) и нужно опираться на них, то необходимо проверять наличие юзера в таблице по `user_id`. Если такого юзера нет - добавлять, если уже есть - обновлять.

Также можно поступить проще: INSERT ON CONFLICT DO.
-- если пользователь уже существует, то просто игнорировать
INSERT INTO 'users' (user_id) VALUES (?) ON CONFLICT(user_id) DO NOTHING

-- если пользователь уже существует, то обновить ему `referrer_id`
INSERT INTO 'users' (user_id, referrer_id) VALUES (?, ?) 
    ON CONFLICT(user_id) DO UPDATE SET referrer_id = excluded.referrer_id
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы