[英]Python SQLAlchemy - How to update database using object within model by a method?
我正在編寫一個簡單的登錄,它使用 PyOTP 庫和 SQLalchemy 和一個 class 我正在使用它工作正常。
一旦使用此驗證,我想將當前 TOTP 保存到數據庫中:
session = Session()
self.lastOtp = currentTotp
session.commit()
session.close()
但它根本不更新數據庫。 我認為這是因為該方法不知道它是特定用戶 object 我正在嘗試更新,但我嘗試將 self 添加到各個行以弄清楚但不能。 我有以下工作:
methodSession = Session()
currentUser = methodSession.query(User).filter_by(emailAddress=self.emailAddress).one()
currentUser.lastOtp = currentTotp
methodSession.commit()
methodSession.close()
self.lastOtp = currentTotp
但這意味着另一個數據庫查詢,我已經有一個用戶 object 可以作為自己訪問。
這是完整用戶 class
# 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
預期行為:
session = Session()
myUser = session.query(User).filter_by(emailAddress='john@smith.com').one()
print("Last OTP: ", myUser.lastOtp)
>>> 987568
myUser.check_secret_key('123456')
>>> True
print("Last OTP: ", myUser.lastOtp)
>>> 123456
myUser.check_secret_key('123456')
>>> False
您需要將要保存的 object 添加到 SQLAlchemy session 中。 我沒有在您的代碼中看到您正在執行此操作。 具體來說,這里:
if totp.verify(secret_key):
session = Session()
self.lastOtp = currentTotp
session.commit()
session.close()
return True
您正在創建 Session,然后提交並關閉它,而不添加要保存到其中的 object 的實例。 您缺少 session.add(...) 調用。
如果User
實例已經與 session 關聯,則可以使用 Session.object_session 檢索session :
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.object_session(self)
self.lastOtp = currentTotp
session.commit()
return True
return False
請注意,提交此 session 將提交已與其關聯的任何其他更改。
看起來 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.