Ejemplos para aclarar la cuestión importante en los comentarios de las respuestas aceptadas
No lo entendí hasta que jugué con él, así que pensé que habría otros que también estarían confundidos. Digamos que está trabajando en el usuario cuyo id == 6
y no_of_logins == 30
cuándo comienza.
# 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
El punto
Al hacer referencia a la clase en lugar de la instancia, puede hacer que SQLAlchemy sea más inteligente sobre el incremento, haciendo que suceda en el lado de la base de datos en lugar del lado de Python. Es mejor hacerlo dentro de la base de datos, ya que es menos vulnerable a la corrupción de datos (por ejemplo, dos clientes intentan aumentar al mismo tiempo con un resultado neto de solo un incremento en lugar de dos). Supongo que es posible hacer el incremento en Python si establece bloqueos o aumenta el nivel de aislamiento, pero ¿por qué molestarse si no tiene que hacerlo?
Una advertencia
Si va a incrementar dos veces a través de un código que produce SQL como SET no_of_logins = no_of_logins + 1
, entonces necesitará confirmar o al menos vaciar entre incrementos, de lo contrario solo obtendrá un incremento en 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