X
X
xpril2022-04-15 21:27:34
Python
xpril, 2022-04-15 21:27:34

When updating data in the sqlite3 database, it updates only 1 row, how can I do it to update everything at once?

The for loop in the database iterates over all vk_id, and when passing them to UPDATE, only one is updated, the very first in the database.

import sqlite3
import vk_api
import datetime
from vk_api.bot_longpoll import VkBotLongPoll, VkBotEventType

token = "token vk"
vk = vk_api.VkApi(token=token)
longpoll = VkBotLongPoll(vk, group_vk_id)

db = sqlite3.connect("vitaliy.db")
qwe = db.cursor()

qwe.execute(""" CREATE TABLE IF NOT EXISTS stata (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    vk_id INTEGER NOT NULL UNIQUE,
    nickname TEXT DEFAULT "Unnamed",
    coins BIGINT DEFAULT 5000,
    prem TEXT DEFAULT "Нет",
    dohod BIGINT DEFAULT 1000
) """)

##################################################################################################

def sender(chat_id, message):
    vk.method("messages.send", {"chat_id": chat_id, "message": message, "disable_mentions": 1, "random_id": 0})


##################################################################################################

while True:
    now = datetime.datetime.now()
    timeC = now.second
    if timeC != datetime.datetime.now().second:
        for i in qwe.execute(""" SELECT vk_id FROM stata """):
            qwe.executemany(""" 
                UPDATE stata
                SET coins = coins + dohod
                WHERE vk_id = ?
            """, (i,))
            db.commit()
    else:
        None
    timeC = datetime.datetime.now().second

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
shurshur, 2022-04-16
@shurshur

cursor.execute returns a generator that returns tuples of values. So in the design:

for i in qwe.execute(""" SELECT vk_id FROM stata """):

the value of i will not be the value of vk_id, but a tuple of one value (vk_id,).
Further, in this cycle, a request is made with (i,), which gives ((vk_id,),), that is, one value. In addition, inside the iteration over the cursor, another query is executed with the same cursor, overwriting the cursor's internal data from the previous query, so nothing is returned when entering the second iteration. It turns out one request for one vk_id. Everything works exactly as written.
What can be done here?
Option 1. In executemany, it makes sense to pass a list not from one value, but from a set (otherwise, there is no point in executemany, the usual execute is simpler). For example, they can be obtained by accumulating in a loop into a list, followed by a separate (outside the loop) call to executemany. But if you don’t need to do anything special with the request data, then the loop is superfluous here, you can get everything at once through fetchall ().
Option 2. Get by with SQL. Examples:
-- добавить всем 1
UPDATE stata SET coins = coins+1;
-- добавить удвоенный доход всем с вип-статусом, если срок его действия ещё не истёк
UPDATE stata SET coins = coins+dohod*2 WHERE vip_status=1 AND vip_status_end>=NOW();

R
rPman, 2022-04-15
@rPman

because there can't be more than 1 entry because of this:


vk_id INTEGER NOT NULL UNIQUE ,

G
galaxy, 2022-04-15
@galaxy

UPDATE stata
   SET coins = coins + dohod

all.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question