Предположим , таблица имеет три колонки: username
, password
и no_of_logins
.
Когда пользователь пытается войти в систему, он проверяет наличие записи с таким запросом, как
user = User.query.filter_by(username=form.username.data).first()
Если пароль совпадает, он продолжает. Я бы хотел подсчитать, сколько раз пользователь входил в систему. Таким образом, всякий раз, когда он успешно входит в систему, я хотел бы увеличить no_of_logins
поле и сохранить его обратно в пользовательскую таблицу. Я не уверен, как выполнить запрос на обновление с помощью SqlAlchemy.
python
sqlalchemy
flask-sqlalchemy
webminal.org
источник
источник
user.no_of_logins += 1
может создавать условия гонки. Вместо этого используйтеuser.no_of_logins = user.no_of_logins + 1
. Переведенный в SQL последний правильный путь будет выглядеть так :SET no_of_logins = no_of_logins + 1
.user.no_of_logins = User.no_of_logins + 1
, или, другими словами, используйте инструментированный атрибут модели для создания выражения SQL. В вашем комментарии показаны 2 способа создания одного и того же состояния гонки.Есть несколько способов
UPDATE
использованияsqlalchemy
источник
setattr(query_result, key, value)
для некоторых обновлений в Flask SQLAlchemy с последующей фиксацией. Есть ли причина отказаться от этого шаблона?setattr(query_result, key, value)
, что в точности эквивалентно написаниюquery_result.key = value
Примеры для разъяснения важного вопроса в комментариях к принятому ответу
Я не понял этого, пока сам не поигрался с этим, поэтому я подумал, что будут и другие, которые тоже будут сбиты с толку. Допустим, вы работаете с пользователем, чей
id == 6
и чейno_of_logins == 30
при запуске.Смысл
Ссылаясь на класс вместо экземпляра, вы можете заставить SQLAlchemy более разумно относиться к приращению, заставляя это происходить на стороне базы данных, а не на стороне Python. Лучше делать это в базе данных, поскольку она менее уязвима для повреждения данных (например, два клиента пытаются выполнить приращение одновременно с чистым результатом только одного приращения вместо двух). Я предполагаю, что в Python можно сделать приращение, если вы установите блокировки или повысите уровень изоляции, но зачем беспокоиться, если вам не нужно?
Предостережение
Если вы собираетесь увеличивать дважды с помощью кода, который производит SQL-подобное
SET no_of_logins = no_of_logins + 1
, вам нужно будет зафиксировать или, по крайней мере, сбросить между приращениями, иначе вы получите только одно приращение всего:источник
С помощью
user=User.query.filter_by(username=form.username.data).first()
оператора вы получите указанного пользователя вuser
переменной.Теперь вы можете изменить значение новой объектной переменной, например,
user.no_of_logins += 1
и сохранить изменения с помощьюsession
метода фиксации.источник
Я написал бота для телеграмм, и у меня проблемы с обновлением строк. Используйте этот пример, если у вас есть модель
Зачем использовать
db.session.flush()
? Вот почему >>> SQLAlchemy: В чем разница между flush () и commit ()?источник
flush()
commit()