it-swarm.com.de

Wie wird der SQLAlchemy-Zeileneintrag aktualisiert?

Angenommen, die Tabelle hat drei Spalten: username, password und no_of_logins.

Wenn der Benutzer versucht, sich anzumelden, wird nach einem Eintrag mit einer Abfrage wie gesucht

user=User.query.filter_by(username=form.username.data).first()

Wenn das Passwort übereinstimmt, fährt er fort. Was ich möchte, ist zu zählen, wie oft sich der Benutzer angemeldet hat. Wenn ich mich also erfolgreich anmeldet, möchte ich das Feld no_of_logins erhöhen und in die Benutzertabelle zurückspeichern. Ich bin nicht sicher, wie Sie die Aktualisierungsabfrage mit SqlAlchemy ausführen.

93
webminal.org
user.no_of_logins += 1
session.commit()
90
Denis

Es gibt verschiedene Möglichkeiten, UPDATE mit sqlalchemy zu verwenden.

1) user.no_of_logins += 1
   session.commit()

2) session.query().\
       filter(User.username == form.username.data).\
       update({"no_of_logins": (User.no_of_logins +1)})
   session.commit()

3) conn = engine.connect()
   stmt = User.update().\
       values(no_of_logins=(User.no_of_logins + 1)).\
       where(User.username == form.username.data)
   conn.execute(stmt)

4) setattr(user, 'no_of_logins', user.no_of_logins+1)
   session.commit()
246
Nima Soroush

Mit Hilfe der Anweisung user=User.query.filter_by(username=form.username.data).first() erhalten Sie den angegebenen Benutzer in der Variable user

Jetzt können Sie den Wert der neuen Objektvariablen wie user.no_of_logins += 1 ändern und die Änderungen mit der Commit-Methode der session speichern.

3
Nilesh

Beispiele zur Verdeutlichung des wichtigen Problems in den Kommentaren der akzeptierten Antwort

Ich habe es nicht verstanden, bis ich selbst damit gespielt habe, also dachte ich, dass es auch andere geben würde, die verwirrt waren. Angenommen, Sie arbeiten an dem Benutzer, dessen id == 6 und dessen no_of_logins == 30 Sie starten.

# 1 (bad)
user.no_of_logins += 1
# result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6

# 2 (bad)
user.no_of_logins = user.no_of_logins + 1
# result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6

# 3 (bad)
setattr(user, 'no_of_logins', user.no_of_logins + 1)
# result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6

# 4 (ok)
user.no_of_logins = User.no_of_logins + 1
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6

# 5 (ok)
setattr(user, 'no_of_logins', User.no_of_logins + 1)
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6

Die Stelle

Indem Sie auf die Klasse anstelle der Instanz verweisen, können Sie SQLAlchemy in Bezug auf das Inkrementieren intelligenter machen und dafür sorgen, dass es auf der Datenbankseite statt auf der Seite Python ausgeführt wird. Dies in der Datenbank zu tun ist besser, da es weniger anfällig für Datenbeschädigungen ist (z. B. versuchen zwei Clients, gleichzeitig mit einem Nettoergebnis von nur einem statt zwei Inkrementen zu inkrementieren). Ich nehme an, es ist möglich, das Inkrementieren in Python durchzuführen, wenn Sie Sperren setzen oder die Isolationsstufe erhöhen, aber warum sollten Sie sich die Mühe machen, wenn Sie dies nicht müssen?

Eine Einschränkung

Wenn Sie zweimal über Code inkrementieren möchten, der SQL wie SET no_of_logins = no_of_logins + 1 erzeugt, müssen Sie zwischen den Inkrementen ein Commit ausführen oder zumindest einen Flush ausführen. Andernfalls erhalten Sie insgesamt nur ein Inkrement:

# 6 (bad)
user.no_of_logins = User.no_of_logins + 1
user.no_of_logins = User.no_of_logins + 1
session.commit()
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6

# 7 (ok)
user.no_of_logins = User.no_of_logins + 1
session.flush()
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6
user.no_of_logins = User.no_of_logins + 1
session.commit()
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6
0
MarredCheese

Ich habe einen Telegramm-Bot geschrieben und habe Probleme mit Update-Zeilen. Verwenden Sie dieses Beispiel, wenn Sie über Modell verfügen

def update_state(chat_id, state):
    try:
        value = Users.query.filter(Users.chat_id == str(chat_id)).first()
        value.state = str(state)
        db.session.flush()
        db.session.commit()
        #db.session.close()
    except:
        print('Error in def update_state')

Warum db.session.flush () verwenden? Das ist, warum >>> SQLAlchemy: Was ist der Unterschied zwischen flush () und commit ()?

0
Andrew Lutsyuk