簡體   English   中英

Python SQLAlchemy - 如何使用 object 中的 object 通過方法 aD98C53 更新數據庫

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM