Ответы пользователя по тегу SQLite
  • Можно ли подключиться к базе данных sqlite3, которая лежит на сервере?

    Vindicar
    @Vindicar
    RTFM!
    sqlite3 требует доступ к файлу именно как к файлу. Так что тебе придётся подмонтировать каталог с базой к целевой машине, тем или иным способом. Под виндой скорее всего только webdav, под никсами вариантов больше.
    Ну и да, sqlite НЕ рассчитана на одновременный доступ, так что если с этой базой кто-то одновременно работает на сервере и на целевой машине, есть шансы что она поломается.
    Так что от "никакая другая" лучше отказаться при первой возможности.

    А для отладочных целей лучше скопировать базу и гонять скрипт на копии, чтобы не угробить "боевую".
    Ответ написан
    Комментировать
  • Не могу запустить пишет Error no such table: users?

    Vindicar
    @Vindicar
    RTFM!
    sqlite3.connect('teor.db')
    Ты уверен, что питоновский скрипт и клиент sqlite открывают один и тот же файл с базой данных?
    Ты указал относительный путь, т.е. путь относительно текущего рабочего каталога. Он может совпадать или не совпадать с каталогом, где лежит скрипт.
    На всякий случай, попробуй так:
    import pathlib, sys
    script_dir = pathlib.Path(sys.argv[0]).parent.resolve()  # путь к каталогу скрипта
    db_file = script_dir / 'teor.db'  # путь к файлу БД
    print(db_file)  # для проверки, какой файл открывается
    conn = sqlite3.connect(db_file)
    ...  # далее по тексту


    Также, попробуй убрать одинарные кавычки вокруг имени таблицы и столбцов. Они обычно нужны, если имя содержит пробелы. В твоём случае только усложняют чтение запроса.
    Ответ написан
    1 комментарий
  • Как получить название столбца sqlite?

    Vindicar
    @Vindicar
    RTFM!
    Поясню ответ выше: если у тебя названия стобцов неизвестны заранее, ты неправильно спроектировал базу данных. Столбцы должны быть неизменны - меняется только набор строк.

    Если у тебя есть ситуация, когда многие сущности связаны со многими (например, отношение "друзья" между пользователями), используй связную таблицу для этого.
    Ответ написан
    2 комментария
  • Как заменить/обновить данные в sqlite (Python)?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, следует различать сценарий "я знаю, что строка есть, её надо обновить" (UPDATE) и "строки может не быть, если так, её надо создать" (INSERT OR REPLACE или INSERT ON CONFLICT UPDATE). Уточни, какой у тебя.

    Во-вторых, приведи код создания таблицы. У тебя link - первичный ключ?
    Ответ написан
  • Как реализовать отправку сообщения ботом при обновлении бд?

    Vindicar
    @Vindicar
    RTFM!
    pochka3648, сделай своё API. Например, первый бот слушает сокет, второй к нему коннектится, и пишет в сокет данные.
    Если не требуется мгновенное оповещение, пусть первый бот периодически проверяет таблицу на наличие новых записей.
    Ответ написан
    Комментировать
  • Как сделать что бы бот выдавал сколько пользователь в боте?

    Vindicar
    @Vindicar
    RTFM!
    В обработчике команды /start записывать в базу текущую дату (например, в виде timestamp).
    По запросу узнать текущую дату, получить дату из базы, вычесть, перевести в дни.
    См. модуль datetime.
    Ответ написан
    Комментировать
  • Как в telegram bot после каждого сообщения пользователя обновлять время в бд?

    Vindicar
    @Vindicar
    RTFM!
    Почитай про INSERT ... ON CONFLICT UPDATE.
    Ответ написан
    Комментировать
  • Как убрать лишние знаки?

    Vindicar
    @Vindicar
    RTFM!
    Ещё один не выучил основы языка, но пытается работать с БД.

    fectchone() возвращает кортеж, в твоём случае кортеж с одним элементом. Скобки - это строковое представление кортежа. Как вытащить значение из кортежа - читай по ссылке.

    Кортежи, списки и словари - это вообще азы языка. Их надо знать, и узнавать с первого взгляда.
    Ответ написан
    Комментировать
  • Sqlite3 операционная ошибка, как исправить?

    Vindicar
    @Vindicar
    RTFM!
    c.execute(f"SELECT * from banking_application WHERE name_p IS {pop}")

    За такое бьют линейкой по пальцам. Собственно, ты уже наткнулся на одну из причин почему. Вторая тут.
    Ну и да, IS используется только как IS NULL или IS NOT NULL. Надо вот так:
    c.execute("SELECT * from banking_application WHERE name_p = ?", pop)
    Ответ написан
  • Как сделать актуализацию данных?

    Vindicar
    @Vindicar
    RTFM!
    Используй on_conflict. Он позволяет как молча проигнорировать втавляемые данные, так и частично обновить существующую строку.
    Причем достаточно конфликта по ключу (id пользователя).

    Собственно, это хорошо работает, если тебе нужно просто хранить в базе всех, кто обращался к твоему боту.
    Если же тебе нужна именно своя регистрация (а тут надо дважды подумать - нужна ли? может, нафиг её?), то тогда сначала проверяй вручную, прошёл ли пользователь регистрацию.
    Ответ написан
    Комментировать
  • Бот на Telebot падает, когда отправляешь второй одинаковый запрос в БД sqllite. Как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Если ты хочешь при любом действии пользователя убедиться, что он в базе, то тебе нужен не просто INSERT, а INSERT ON CONFLICT IGNORE или INSERT ON CONFLICT UPDATE. Если тебе требуется что-то обновлять (например, хранить для пользователя момент последнего обращения к боту), то нужен второй. Если не требуется, то лучше первый.
    Ответ написан
    Комментировать
  • Не работает условие Python, SQLite как решить и почему?

    Vindicar
    @Vindicar
    RTFM!
    1. chat_verification = {message.chat.id}
    chat_verification - это множество из одного элемента, вместо простого значения. Зачем?
    2.
    cursor.execute(f"SELECT chat_id FROM chat_id_table WHERE chat_id ='{chat_verification}' AND verification = 1")

    Никогда не используй f-строки. С целыми числами прокатит, со строками - очень рискованно. Используй подстановку параметров.
    cursor.execute("SELECT chat_id FROM chat_id_table WHERE chat_id = ? AND verification = 1", (message.chat.id, ))

    3.
    check = cursor.execute(...
    if check is True:

    execute() вернёт ссылку на всё тот же cursor, независимо от запроса. Тебе нужно выбрать строку из этого курсора с помощью метода fetchone(). Метод вернёт или кортеж с одним значением chat_id, или None, если ни одна строка не удовлетворяет условию.
    cursor.execute("SELECT chat_id FROM chat_id_table WHERE chat_id = ? AND verification = 1", (message.chat.id, ))
    result = cursor.fetchone()
    if result is None:
        print('Нет такой строки')
    else:
        chat_id = result[0]
        print('есть результат:', chat_id)
    Ответ написан
  • Как сделать условие в SQLite Python?

    Vindicar
    @Vindicar
    RTFM!
    Ну так у тебя второй запрос запршивает всех пользователей, без условия.
    А вообще приведённый код не имеет смысла и не должен работать вообще никак.
    for i in cursor.fetchone("SELECT ID FROM user_info WHERE RANK = '1'"):

    Ты перебираешь столбцы в первой строке (fetchone), для которой RANK = '1'. Это при том, что запрос возвращает тебе только один столбец - ID. А ещё метод fetchone() не принимает параметров. Ты пропустил вызов execute()?

    Потом ты почему-то берёшь 0й символ этого столбца. Если он равен 1 (а он не будет равен 1, так как это символ, а не число).
    Потом ты перебираешь всех пользователей, и отправляешь им сообщения (при этом у тебя в вызове send_message() две опечатки - в имени переменной и незакрытая скобка).

    А ещё у тебя отступы кривые - почему for i с отступом?

    В общем, по такой бредятине понять, в чём дело, нереально.
    Ответ написан
    4 комментария
  • Как решить проблему с SQLite3?

    Vindicar
    @Vindicar
    RTFM!
    С чего ты взял, что возвращаемое значение второй раз будет не None? Ты проверял, что данные заносятся?
    Собственно, в том и ошибка - у тебя уже есть запись с таким userid, второй раз вставить нельзя.

    А твоя GetInfo() не работает. Почему? Внезапно, в SQL сравнение - это =, а не ==. А ошибку тебе не пишет, потому что ты сделал except: pass. За такую практику вообще надо бить по пальцам линейкой, надеюсь, ты теперь понял почему.
    Ну и до кучи, если хочешь проверить существование, то лучше сделать запрос вида SELECT COUNT(*) FROM main WHERE user_id = ? или
    SELECT EXISTS(SELECT * FROM main WHERE user_id = ?)
    . Эти запросы гарантированно вернут одну строку с одним значением, 0 или 1. 0 - строка не существует, 1 - строка существует.
    Ответ написан
    1 комментарий
  • Стакаются ли sqlite и тг бот?

    Vindicar
    @Vindicar
    RTFM!
    1. Что значит "одновременного вноса"? sqlite не потокобезопасна, но если ты используешь асинхронную библиотеку для телеги с дефолтной реализацией event loop, то у тебя никогда не будут выполняться 2 обработчика одновременно. Дефолтная реализация строго однопоточна, и проблем с sqlite не будет.
    2. 500 человек - это не мера нагрузки. Самая примитивная мера нагрузки - обращений к базе в единицу времени.
    А вообще более точно было бы проводить измерение времени выполнения разных частей обработчика события. Если бот потребляет значительную долю ресурсов своего хостинга и при этом проводит много времени обращаясь к БД - вот тогда стоит задуматься о смене БД. И даже тогда можно сначала посмотреть в сторону aiosqlite, чтобы не тормозить всего бота, пока запрос к БД выполняется.
    Ответ написан
    Комментировать
  • TelegramBot + SQLite?

    Vindicar
    @Vindicar
    RTFM!
    Ну технически возможно: sqlite позволяет описывать user defined functions, которые можно вызывать внутри SQL-запросов - в том числе внутри триггеров. Вот только большой вопрос, что это за функции. С асинхронщиной могут быть проблемы.

    Но честно, я бы лучше сделал простой поллинг. Запросил все записи позднее заданного времени, если такие записи есть - обработал, заменил заданное время на самое позднее из этих записей. Повторять раз в пять минут.
    Да, время реакции медленнее, но зато код куда понятнее, и проще портируется на другую БД, если что.
    Ответ написан
    3 комментария
  • Как сделать вывод определённого количества столбцов?

    Vindicar
    @Vindicar
    RTFM!
    Читай про операторы LIMIT и OFFSET у SQL-запроса.
    Если размер страницы N записей, то для выдачи страницы i тебе нужно будет задать OFFSET (i - 1) * N LIMIT N.
    Разумеется, нужно также задать порядок сортировки записей через ORDER BY.
    Ответ написан
    Комментировать
  • Почему не записываются данные в бд?

    Vindicar
    @Vindicar
    RTFM!
    def user_exists(self, user_id):
        with self.connection:
            ...
    def add_user(self, user_id):
        with self.connection:


    По выходу из блока with соединение закроется. Второй блок with его уже не переоткроет.
    В таких ситуациях блок with использовать не надо.
    Ответ написан
    Комментировать
  • Наработает цикл for в цикле while что делать?

    Vindicar
    @Vindicar
    RTFM!
    Ну положим, в первом коде ты делаешь запрос с Num_bd = 0, а во втором ты начинаешь с Num_bd = 1 и так далее. У тебя в БД точно есть подходящие данные?
    Кроме того, else для for работает не так как ты думаешь. Ветка else отработает, если цикл for не был прерван оператором break.
    Ответ написан