Beispiele zur Klärung des wichtigen Problems in den Kommentaren der akzeptierten Antwort
Ich habe es nicht verstanden, bis ich selbst damit herumgespielt 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
beim Start.
# 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
Der Punkt
Indem Sie auf die Klasse anstelle der Instanz verweisen, können Sie SQLAlchemy beim Inkrementieren intelligenter machen und dies auf der Datenbankseite anstelle der Python-Seite veranlassen. 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 erhöhen). Ich gehe davon aus, dass es möglich ist, 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-ähnliche Effekte erzeugt SET no_of_logins = no_of_logins + 1
, müssen Sie zwischen den Inkrementen ein Commit durchführen oder zumindest einen Flush durchfü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