Примеры для разъяснения важного вопроса в комментариях к принятому ответу
Я не понял этого, пока сам не поигрался с этим, поэтому я подумал, что будут и другие, которые тоже будут сбиты с толку. Допустим, вы работаете с пользователем, чей id == 6
и чей no_of_logins == 30
при запуске.
# 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
Смысл
Ссылаясь на класс вместо экземпляра, вы можете заставить SQLAlchemy более разумно относиться к приращению, заставляя это происходить на стороне базы данных, а не на стороне Python. Лучше делать это в базе данных, поскольку она менее уязвима для повреждения данных (например, два клиента пытаются выполнить приращение одновременно с чистым результатом только одного приращения вместо двух). Я предполагаю, что в Python можно сделать приращение, если вы установите блокировки или повысите уровень изоляции, но зачем беспокоиться, если вам не нужно?
Предостережение
Если вы собираетесь увеличивать дважды с помощью кода, который производит SQL-подобное SET no_of_logins = no_of_logins + 1
, вам нужно будет зафиксировать или, по крайней мере, сбросить между приращениями, иначе вы получите только одно приращение всего:
# 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