Exemples pour clarifier la question importante dans les commentaires de la réponse acceptée
Je ne l'ai pas compris avant d'avoir joué avec, et je me suis dit que d'autres personnes seraient également déroutées. Disons que vous travaillez sur l'utilisateur dont id == 6
et dont no_of_logins == 30
quand vous commencez.
# 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
Le point
En faisant référence à la classe plutôt qu'à l'instance, vous pouvez faire en sorte que SQLAlchemy soit plus intelligent en matière d'incrémentation, en faisant en sorte que cela se passe du côté de la base de données plutôt que du côté de Python. Il est préférable de le faire dans la base de données car il est moins vulnérable à la corruption des données (par exemple, deux clients tentent d'incrémenter en même temps avec un résultat net d'un seul incrément au lieu de deux). Je suppose qu'il est possible d'effectuer l'incrémentation en Python si l'on pose des verrous ou si l'on augmente le niveau d'isolation, mais à quoi bon si ce n'est pas nécessaire ?
Un avertissement
Si vous allez incrémenter deux fois via un code qui produit du SQL comme SET no_of_logins = no_of_logins + 1
vous devrez alors vous engager ou au moins faire une purge entre les incréments, sinon vous n'obtiendrez qu'un seul incrément au total :
# 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