Как добавить новое значение в столбец 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. Следите за структурой таблицы и ограничениями. При необходимости хранить множество записей для одного пользователя создавайте отдельные таблицы с внешними ключами.