假设表有三列:username
,password
和no_of_logins
。
当用户尝试登录时,将使用查询之类的内容检查条目
user = User.query.filter_by(username=form.username.data).first()
如果密码匹配,他将继续。我想做的是计算用户登录的次数。因此,无论他何时成功登录,我都希望增加该no_of_logins
字段并将其存储回用户表。我不确定如何使用SqlAlchemy运行更新查询。
假设表有三列:username
,password
和no_of_logins
。
当用户尝试登录时,将使用查询之类的内容检查条目
user = User.query.filter_by(username=form.username.data).first()
如果密码匹配,他将继续。我想做的是计算用户登录的次数。因此,无论他何时成功登录,我都希望增加该no_of_logins
字段并将其存储回用户表。我不确定如何使用SqlAlchemy运行更新查询。
Answers:
user.no_of_logins += 1
session.commit()
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
,换句话说,使用模型的Instrumented属性生成SQL表达式。因为它是您的注释,所以显示了两种产生相同竞态条件的方法。
有几种UPDATE
使用方法sqlalchemy
1) user.no_of_logins += 1
session.commit()
2) session.query().\
filter(User.username == form.username.data).\
update({"no_of_logins": (User.no_of_logins +1)})
session.commit()
3) conn = engine.connect()
stmt = User.update().\
values(no_of_logins=(User.no_of_logins + 1)).\
where(User.username == form.username.data)
conn.execute(stmt)
4) setattr(user, 'no_of_logins', user.no_of_logins+1)
session.commit()
setattr(query_result, key, value)
Flask SQLAlchemy中的一些更新,然后进行提交。有什么理由打折这种模式?
setattr(query_result, key, value)
,它等同于写作query_result.key = value
直到我自己玩弄它之前,我都不了解它,所以我认为还会有其他人感到困惑。假设您正在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
我写了电报bot,并且在更新行时遇到了一些问题。如果您有模型,请使用此示例
def update_state(chat_id, state):
try:
value = Users.query.filter(Users.chat_id == str(chat_id)).first()
value.state = str(state)
db.session.flush()
db.session.commit()
#db.session.close()
except:
print('Error in def update_state')
为什么要使用db.session.flush()
?这就是为什么>>> SQLAlchemy:flush()和commit()有什么区别?
flush()
总是被称为呼叫的一部分commit()
”