Как добавить новое значение в столбец SQLite, а не обновлять существующее

    При работе с базами данных SQLite в Python часто возникает задача: добавить новую запись в таблицу, но при повторном вызове с теми же параметрами данные обновляются, а не вставляются. Это типичная ситуация, когда используется команда UPDATE вместо INSERT. Давайте разберёмся, как правильно выполнять вставку новых строк, сохраняя все предыдущие записи.

    В чём разница между UPDATE и INSERT

    Команда UPDATE изменяет существующие строки, соответствующие условию WHERE. Если условию не соответствует ни одна строка, обновление не происходит. Команда INSERT добавляет новую строку в таблицу, независимо от наличия других записей. В вашем коде используется UPDATE users SET my_ref_sub = ? WHERE user_id = ?, что приводит к замене значения в столбце my_ref_sub для заданного user_id.

    Как исправить код для добавления новых значений

    Чтобы каждый раз добавлять новую запись, замените UPDATE на INSERT:

    async def set_my_ref_sub(self, user_id, sub):
        async with self.lock:
            async with aiosqlite.connect(path_to_db) as db:
                cursor = await db.cursor()
                await cursor.execute("INSERT INTO `users` (`user_id`, `my_ref_sub`) VALUES (?, ?)", (user_id, sub))
                await db.commit()

    Особенности структуры таблицы

    Убедитесь, что в таблице users нет ограничения UNIQUE на столбец user_id, иначе INSERT вызовет ошибку дублирования. Если вам нужно хранить несколько подписок для одного пользователя, рекомендуется создать отдельную таблицу user_subscriptions со столбцами user_id и subscription, где user_id не является уникальным.

    Пример для нескольких значений

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

    CREATE TABLE user_subscriptions (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        user_id INTEGER NOT NULL,
        subscription TEXT NOT NULL
    );

    Тогда код вставки будет таким:

    async def add_subscription(self, user_id, sub):
        async with self.lock:
            async with aiosqlite.connect(path_to_db) as db:
                cursor = await db.cursor()
                await cursor.execute("INSERT INTO user_subscriptions (user_id, subscription) VALUES (?, ?)", (user_id, sub))
                await db.commit()

    Проверка на дубликаты

    Если нужно избежать повторения одинаковых пар user_id и sub, добавьте UNIQUE-ограничение на оба столбца:

    CREATE TABLE user_subscriptions (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        user_id INTEGER NOT NULL,
        subscription TEXT NOT NULL,
        UNIQUE(user_id, subscription)
    );

    Тогда INSERT OR IGNORE пропустит дубликат, а INSERT OR REPLACE обновит существующую запись.

    Заключение

    Для добавления новых значений в SQLite используйте INSERT, а не UPDATE. Следите за структурой таблицы и ограничениями. При необходимости хранить множество записей для одного пользователя создавайте отдельные таблицы с внешними ключами.

    Часто задаваемые вопросы