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.
user.no_of_logins += 1
session.commit()
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()
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.
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
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?
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
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 ()?