Ответы пользователя по тегу SQLite
  • SQLite + Python, как проверить есть ли данные в базе?

    @o5a
    Проще всего в цикле перебирать значения и для каждого без проверки просто запускать запрос на вставку, используя дополнительное on conflict - он позволит игнорировать команду при наличии этого значения в базе.
    for n in res:
        c.execute('INSERT INTO Zayavka(id) VALUES(?) ON CONFLICT(id) DO NOTHING', (n, ) )


    Вместо цикла можно использовать c.executemany, который сам последовательно применит команду ко всем элементам списка, но это должен быть вложенный список, где каждый элемент - набор данных для одной строки, т.е.
    res = [[40065], [40064]]
    c.executemany('INSERT INTO Zayavka(id) VALUES(?) ON CONFLICT(id) DO NOTHING', res )
    Ответ написан
    Комментировать
  • Работа с Pandas. Почему в Excel не передаются данные из db?

    @o5a
    Т.к. не задали никаких условий, то запрос
    select * from users, orders, items, commands, cats
    просто формирует кросс-соединение указанных таблиц (каждая строка каждой таблицы перемножаются друг на друга). В колонках Excel и записываются все поля всех этих таблиц.

    "только заголовки" потому что данных в таблицах нет (или не записали еще, или забыли закомитить).

    Сомневаюсь, что хотели делать кросс-соединение, так что надо указать параметры объединения таблиц, или через where .. = .. или через join
    Например так (зависит от ваших реальных связей между таблицами):
    select * from users u join orders o on u.user_id = o.user_id
    Ответ написан
  • Как передать значение в команду sqlite3?

    @o5a
    Подстановка значений в таком виде НЕ работает для идентификаторов, которыми являются названия таблиц и полей. В данном случае подставить можно через обычное форматирование строки:
    cur.execute("SELECT COUNT(*) FROM users WHERE {} == 1".format(mmml))
    или
    cur.execute(f"SELECT COUNT(*) FROM users WHERE {mmml} == 1")

    Возможно правильнее будет изменить сами таблицы, ведь эти нумерованные n1...6 похожи на какие-то костыли.
    Ответ написан
    2 комментария
  • Как решить данную проблему с SQLite?

    @o5a
    Как уже объяснили, если пользователя нет, то и данных не возвратит, в результате цикла не будет. Простым изменением можно просто возврат результата внести внутрь цикла:
    ...
                for row in result:
                    singup = str(row[0])
                    return singup

    или же напрямую
    ...
                for row in result:
                    return str(row[0])

    В таком случае если пользователь есть, то вернет его данные. Если нет, то None. И если специальные параметры соединения не указывали, то row итак возвращает текстом, так что можно просто:
    return row[0]
    Ответ написан
    Комментировать
  • Как правильно хранить в Sqlite числа с плавающей точкой что бы в дальнейшем удобно производить выборку по этим данным?

    @o5a
    Вы что-то намудрили при создании таблицы. У вас тип полей не real, а BLOB, это бинарный тип. Поэтому он и выдает такие значения. Возможно до этого экспериментировали и создали таблицу с типом BLOB, поэтому новая с типом REAL не пересоздалась. Грохните ее и создайте заново. Будет выдавать нормальные типы (real из sqlite должен выдавать как float)
    И заодно, по поводу структуры. Создавать 256 полей под 256 значений выглядит не очень, да и удобство сомнительное. Лучше было их записывать построчно, с нумерацией, т.е. таблица вида:
    (id_photo, h_num, h_value)
    тогда и запись будет не так монструозно выглядеть, и запрашивать нужное значение тоже удобно будет
    select * from photos where id_photo = ... and h_num = 1
    или
    select * from photos where h_num = 1 and h_value > 30
    Ответ написан
    1 комментарий
  • Правильно ли связанны мои таблицы в sqlite?

    @o5a
    1. Лучше не разделять таблицы с фото на 2 разных. Судя по описанию задачи структура и хранимые в них данные абсолютно идентичны по сути. Так что лучше использовать единственную таблицу для хранения всех этих вариантов фото. А для разделения (лицо/котики/возможно еще какой вариант захотите добавить) использовать отдельное поле в таблице, photo_type например.
    2. В представленном коде у Вас из таблицы фотографий идет FK на таблицу пользователей. Если таблица фото предполагает хранение самих данных (что за поле h1? это сами данные фото?), то правильнее сделать наоборот: в таблице пользователей хранить id из таблицы фото, с соответствующим FK.
    Т.е. примерно так
    CREATE TABLE IF NOT EXISTS users(user_id INTEGER  NOT NULL PRIMARY KEY, 
                    photo_id INTEGER NOT NULL, 
                    registration_date TEXT, 
                    actual_name TEXT, 
                    real_name TEXT, 
                    old_names TEXT, 
                    friends INT, 
                    level INT, 
                    country TEXT, 
                    profile_summary TEXT, 
                    src TEXT,
    FOREIGN KEY (photo_id) REFERENCES photos(id))
    
    CREATE TABLE IF NOT EXISTS photo_type(photo_type INTEGER PRIMARY KEY,
                      photo_type_name TEXT)
    
    CREATE TABLE IF NOT EXISTS photos(id INTEGER PRIMARY KEY AUTOINCREMENT,
                      photo_type INTEGER,
                      h1 INT,
    FOREIGN KEY (photo_type) REFERENCES photo_type(photo_type))

    3. По формату данных. Можно хранить как INT, FLOAT, насколько знаю там еще вроде можно NUMERIC, это как аналог десятичного числа.
    6.1000e+01

    А точно у Вас десятичные числа? Приведенный пример по факту целое число 61.
    массив из 256 не целых чисел в базу(гистограмму картинки)

    Как таковых массивов sqlite насколько знаю не поддерживает. Чтобы хранить придется заносить каждое число в отдельную строку с соблюдением порядка (id autoincrement в принципе с этим справится). Не факт, что это лучший вариант хранения этих данных, ведь по факту насколько я понимаю никогда не понадобится выбрать конкретное число из этой гистограммы, она нужна всегда только как массив - полностью записываем, полностью считываем.
    Так что для такой задачи возможно лучше не плодить их в таблице, а просто завести текстовое поле и хранить там этот список чисел в виде json. В sqlite можно даже написать автоматическое преобразование данных, т.е. в колонку пишется список, а сохраняется как json, аналогично при чтении. Пример.
    Ответ написан
    Комментировать
  • Как выбрать значения, которые были загружены день назад от даты в таблице?

    @o5a
    c.execute("select * from mytable where date < date('now', '-1 day')")
    Ответ написан
    Комментировать
  • Ошибка sqlite3.OperationalError: no such column: cash, как решить?

    @o5a
    Значит в таблице нет такого поля cash.
    По всей видимости таблицу создавали изначально с другим составом полей, и она уже есть в базе (без cash), поэтому CREATE IF NOT EXISTS пропускается.

    Или удалите таблицу из базы, если данные не нужны: "DROP TABLE users"

    Или добавьте поле отдельно: "ALTER TABLE users ADD cash BIGINT".
    Ответ написан
    1 комментарий
  • Как сделать вывод одной определенной строки из БД?

    @o5a
    При данной постановке оптимально было бы выбрать все значения из базы в список (один раз, без сортировок), а затем перемешать его и при каждом запросе выдавать следующее значение по списку.
    # считать все свои тексты в список
    data = [row[0] for row in cur.execute("SELECT name FROM `test`")]
    random.shuffle(data) # теперь данные в рандомном порядке, можно выбирать последовательно


    Альтернативный вариант (допустим, этих текстовых данных в таблице очень много и может быть не эффективно тянуть и хранить их все сразу), считать список номеров, также отсортировать и при каждом запросе пользователя делать запрос к базе уже по номеру.

    # считать только уникальные номера этих текстов в список
    numbers = [row[0] for row in cur.execute("SELECT number FROM `test`")]
    random.shuffle(numbers) # теперь данные в рандомном порядке, можно выбирать последовательно
    
    # при запросе пользователя берем следующий номер из нашего рандомного списка
    number = ...
    # и по нему уже достаем сам текст из базы
    text = cur.execute("SELECT name FROM `test` where number = ?", (number, )).fetchone()[0]
    Ответ написан
    Комментировать
  • Как боту вывести топ 5 пользователей из sqlite3?

    @o5a
    cur.execute("SELECT * FROM users ORDER BY money DESC LIMIT 5")
    data = cur.fetchall()
    text = '\n'.join(f'{row[1]}:   {row[5]} - монет' for row in data)
    await message.reply(text)
    Ответ написан
    Комментировать
  • Почему не работает sql запрос в условиях?

    @o5a
    После изменения данных нужно делать
    connection.commit()
    Ответ написан
    Комментировать
  • Как отдельно вывести каждое значение из бд?

    @o5a
    Результат выполнения select в курсоре, как и fetchall() выдает не просто кортеж, а вложенный кортеж, т.е.
    ((ряд1значение1, ряд1значение2, ряд1значение3... ), (ряд2значение1, ряд2значение2, ряд2значение3... ), ...)

    соответственно нужно дополнительно join складывать значения ряда в строку, а затем строки рядов в строку.
    result2 = '\n'.join(' ║ '.join(f'{val}' for val in row) for row in cur.execute(f"SELECT * FROM {arg}"))

    А если нужно, чтобы это было выровнено, то можно сначала считать данные, затем вычислить в каждом столбце самое длинное значение, и затем уже вывести, отформатировав по наибольшему.
    Ответ написан
    1 комментарий
  • Как исправить sqlite3.IntegrityError: NOT NULL constraint failed?

    @o5a
    В таблице поля объявлены обязательными (нельзя вставить NULL), что в целом нормально. Но при этом нельзя заносить данные постепенно, нужно делать INSERT один раз в самом конце, когда все данные от пользователя получили, т.е. в функции patronymic.
    def patronymic(message): #получаем отчества
        ...
        cursor.execute("INSERT INTO Profile (user_id, name, surname, patronymic) VALUES (?, ?, ?, ?)", (user_id, name, surname, patronymic))
    Ответ написан
    5 комментариев
  • Как добавить число к числу из бд sqlite?

    @o5a
    number = # на сколько нужно увеличить то число
    cur.execute("UPDATE users SET number = number + ? WHERE user_id = ?", (number, user_id))
    Ответ написан
    7 комментариев
  • Как боту aiogram вывести число из бд sqlite?

    @o5a
    В функции exists_user как раз правильно составлен запрос на выбор конкретного пользователя (с использованием WHERE).
    Аналогично должен быть составлен и запрос в функции number. В текущем виде тот запрос выбирает всех подряд.
    Для передачи самого номера пользователя в команду нужно достать его из параметров:
    async def number(message: types.Message):
        num = message.get_args()
    Ответ написан
    5 комментариев
  • Проблема с Telebot Python Sqlite3?

    @o5a
    Потому что текстовые строки складываются не так, как числа.
    sql.execute("UPDATE users SET name = name || '\n' || ? WHERE login = ?", (name_for_table, message.from_user.id))

    А для чего вообще это добавление на новой строке понадобилось?
    Ответ написан
    Комментировать
  • Как найти пользователя в БД Sqlite3 Python?

    @o5a
    Почитайте основы SQL (например https://proglib.io/p/sql-for-20-minutes)

    Для получения информации там есть своя система фильтров. В данном случае просто
    cur.execute("SELECT * FROM users WHERE id = ?", (id, ))
    all = cur.fetchone()

    в all будет запись с этим пользователем, если есть, или None, если отсутствует.
    или так
    cur.execute("SELECT COUNT(*) FROM users WHERE id = ?", (id, ))
    cnt = cur.fetchone()[0]
    в cnt будет кол-во записей с этим пользователем, т.е. 1 если есть, 0 если нет.
    Ответ написан
    Комментировать
  • Не работает функция как надо,что делать?

    @o5a
    def starvation_system():
        db = sqlite3.connect("base.db") # подключение базы данных.
        sql = db.cursor()
        sql.execute("UPDATE users SET golod = golod - 10")
        db.commit()
    Ответ написан
    Комментировать
  • Вывод данных из бд в свой профиль telegram bot python?

    @o5a
    Если удобнее, то можно получать данные в виде словаря (где ключи - названия столбцов). Тогда можно напрямую обращаться к нужному полю по имени.
    class SQLighter:
      def __init__(self, database):
          self.connection = sqlite3.connect(database, check_same_thread = False)
          self.connection.row_factory = sqlite3.Row # этой строкой указываем, что результат получаем в виде словаря
          self.cursor = self.connection.cursor()
          self.cursor.execute("CREATE TABLE IF NOT EXISTS stats (user_id INT, user_name TEXT, survived INT, infected INT)")
    ...
      # и можно сделать такую функцию, возвращающую всю информацию пользователя
      def get_info(self, id):
          with self.connection:
              return self.cursor.execute("SELECT * FROM stats WHERE user_id=?", (id, )).fetchone()
    
    sql_lighter = SQLighter("database.db")
    sql_lighter.add_user(982543922, "Владимир", 1, 1)
    # затем получаем весь словарь данных и можем использовать любые нужные поля из него
    data = sql_lighter.get_info(982543922)
    print(data)
    print(data['user_name'])
    print("Информация пользователя {}: имя: {}, survived: {}, infected: {}".format(data['user_id'], data['user_name'], data['survived'], data['infected']))
    Ответ написан
    7 комментариев
  • Как отсортировать по ORDER BY используя ещё и rowid?

    @o5a
    Но хотелось бы как-то отсортировать это по cash и уже получить rowid .

    Не путайте понятия
    rowid - фиксированный уникальный идентификатор для записей столбца, не зависящий от сортировок (но при некоторых условиях может меняться, в зависимости от объявления).
    "место юзера в таблице" при разных сортировках будет разным.
    Так что все-таки требуется? Выяснить rowid пользователя по id (что само по себе нелепо, т.к. id сам по себе должен быть уникальный, нет смысла по нему искать rowid)? Или же найти относительный номер пользователя в отсортированном списке?
    Если второе - тогда есть row_number, в котором указывается сортировка. Так например можно получить место пользователей по голосовой активности
    SELECT id, name, cash, row_number() over(order by cash desc) as rownum FROM users

    И соответственно найти порядковый номер пользователя при такой сортировке
    cursor.execute("SELECT cash, rowid, rownum FROM (SELECT id, name, cash, row_number() over(order by cash desc) as rownum FROM users) WHERE id = ?", (ctx.author.id, )).fetchone()[2]

    rowid и rownum соответственно будут разными (1-й - идентификатор в таблице, 2-й - порядковый номер в сортировке). Т.е. для пользователя с макс. количеством cash rownum будет равен 1, а rowid в зависимости от его идентификатора в таблице.
    Ответ написан
    1 комментарий