PythonSqlAlchemy-如何通过方法使用模型内的对象更新数据库?
我正在使用PyOTP库和SQLalchemy编写一个简单的登录名,该登录名具有一次性密码,我正在使用一个工作正常的类 我希望使用以下方法验证后将当前TOTP保存到数据库中:PythonSqlAlchemy-如何通过方法使用模型内的对象更新数据库?,python,python-3.x,sqlalchemy,Python,Python 3.x,Sqlalchemy,我正在使用PyOTP库和SQLalchemy编写一个简单的登录名,该登录名具有一次性密码,我正在使用一个工作正常的类 我希望使用以下方法验证后将当前TOTP保存到数据库中: session = Session() self.lastOtp = currentTotp session.commit() session.close() 但它根本不会更新数据库。我认为这是因为该方法不知道它是我试图更新的特定用户对象,但我尝试将self添加到不同的行中以找出它,但无法。我有以下工作经验: method
session = Session()
self.lastOtp = currentTotp
session.commit()
session.close()
但它根本不会更新数据库。我认为这是因为该方法不知道它是我试图更新的特定用户对象,但我尝试将self添加到不同的行中以找出它,但无法。我有以下工作经验:
methodSession = Session()
currentUser = methodSession.query(User).filter_by(emailAddress=self.emailAddress).one()
currentUser.lastOtp = currentTotp
methodSession.commit()
methodSession.close()
self.lastOtp = currentTotp
但这意味着另一个数据库查询,我已经有了一个用户对象,我可以自己访问它
这是完整的用户类
# user class
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
firstName = Column(String(64))
lastName = Column(String(64))
emailAddress = Column(String(128), index=True, unique=True)
passwordHash = Column(String(128))
secretKey = Column(BLOB)
lastOtp = Column(String(128))
def __repr__(self):
return '<User {}>'.format(self.emailAddress)
def set_password(self, password):
# function to set password hash
self.passwordHash = generate_password_hash(password)
def check_password(self, password):
# function to check password returning true or false
return check_password_hash(self.passwordHash, password)
def set_secret_key(self):
# function to set the secure secret key
pass
def get_secret_key(self):
# function to return the secure secret key
pass
def check_secret_key(self, secret_key):
# function to check the otp returning true or false
totp = pyotp.TOTP(self.get_secret_key())
currentTotp = totp.now()
if self.lastOtp == currentTotp:
return False
if totp.verify(secret_key):
session = Session()
self.lastOtp = currentTotp
session.commit()
session.close()
return True
return False
您需要将要保存的对象添加到SQLAlchemy会话。我在你的代码中看不到你在做什么。 具体而言,这里:
if totp.verify(secret_key):
session = Session()
self.lastOtp = currentTotp
session.commit()
session.close()
return True
您正在创建会话,然后提交并关闭它,而不向其中添加要保存的对象的实例。缺少会话。添加(…)调用。需要将要保存的对象添加到SQLAlchemy会话。我在你的代码中看不到你在做什么。 具体而言,这里:
if totp.verify(secret_key):
session = Session()
self.lastOtp = currentTotp
session.commit()
session.close()
return True
您正在创建会话,然后提交并关闭它,而不向其中添加要保存的对象的实例。您缺少会话。添加(…)呼叫。看起来Matei的评论意味着这是唯一的解决方案:
def check_secret_key(self, secret_key):
# function to check the otp returning true or false
totp = pyotp.TOTP(self.get_secret_key())
currentTotp = totp.now()
if self.lastOtp == currentTotp:
return False
if totp.verify(secret_key):
methodSession = Session()
currentUser = methodSession.query(User).filter_by(emailAddress=self.emailAddress).one()
currentUser.lastOtp = currentTotp
methodSession.commit()
methodSession.close()
self.lastOtp = currentTotp
return True
return False
看起来Matei的评论意味着这是唯一的解决方案:
def check_secret_key(self, secret_key):
# function to check the otp returning true or false
totp = pyotp.TOTP(self.get_secret_key())
currentTotp = totp.now()
if self.lastOtp == currentTotp:
return False
if totp.verify(secret_key):
methodSession = Session()
currentUser = methodSession.query(User).filter_by(emailAddress=self.emailAddress).one()
currentUser.lastOtp = currentTotp
methodSession.commit()
methodSession.close()
self.lastOtp = currentTotp
return True
return False
如果
用户
实例已与会话关联,则可使用以下方法检索该会话:
请注意,提交此会话将提交已与其关联的任何其他更改。如果
用户
实例已与会话关联,则可以使用以下方法检索该会话:
请注意,提交此会话将提交与之相关的任何其他更改。我已更新了问题。我知道我可以添加一个完整的新查询(现在包括示例代码)并保存,但是我已经有了用户对象,已经打开了一个数据库连接,并且我已经更新了self.lastOtp。如何更新数据库。添加与我正在更新的数据库无关。即使您之前更新了同一个实例,您在check\u secret\u key中创建的新会话也不知道您要保存的对象。保存之前,必须将对象附加到正在创建的会话。我已更新了问题。我知道我可以添加一个完整的新查询(现在包括示例代码)并保存,但是我已经有了用户对象,已经打开了一个数据库连接,并且我已经更新了self.lastOtp。如何更新数据库。添加与我正在更新的数据库无关。即使您之前更新了同一个实例,您在check\u secret\u key中创建的新会话也不知道您要保存的对象。在保存之前,您必须将对象附加到正在创建的会话。您的
用户
对象是否已与会话关联(即,您通过查询数据库获得该对象)?是的,我已经有一个会话,我已查询过该会话,如下所示:myUser=Session.query(User).filter\u by(emailAddress=)john@smith.com"(一)当我运行myUser.check_secret_key('123456')时,如果它正确,预期的行为是返回True并更新john@smith.com用户在当前对象和数据库中的最后一个OTP都是123456,因此如果再次使用123456,它将返回FALSE,即您的用户
对象是否已与会话关联(也就是说,您是通过查询数据库得到的)?是的,我已经有了一个会话,我已经查询过了,就像myUser=session.query(User).filter_by(emailAddress=)john@smith.com“).one()当我运行myUser时。检查密钥('123456')如果正确,则预期的行为是返回True并更新john@smith.com用户在当前对象和数据库中的最后一个OTP都是123456,因此如果再次使用123456,它将返回FalseThank Thank man-在函数之外进行了一些调整后,该函数仍然有效..:-)真的很感激这个汉克人——在函数之外做了几次调整后,他就成功了真的很感激