Sqlalchemy:自动计算另一列更改后的列值

时间:2016-11-01 07:53:05

标签: python sqlalchemy

我希望使用方法计算列(is_dangerous_token)的值。 这是我到目前为止所做的事情。

class PassRecovery(DeclarativeBase):
    __tablename__ = 'pass_recoveries'

    id = Column(Integer, primary_key=True)
    account_email_address = Column(Unicode(255), ForeignKey('accounts.email_address'), index=True)
    account = relationship('Account', backref=backref('pass_recoveries', cascade='all, delete-orphan'))
    _is_dangerous_token = Column('is_dangerous_token', Unicode(255))

    def _set_is_dangerous_token(self, account_email_address):
        secret_key = config.get('is_dangerous_key')
        signer = TimestampSigner(secret_key)
        self._is_dangerous_token = signer.sign(account_email_address)

    def _get_is_dangerous_token(self):
        return self._is_dangerous_token

    is_dangerous_token = synonym(
        '_is_dangerous_token',
        descriptor=property(_get_is_dangerous_token, _set_is_dangerous_token)
    )

但问题是,当我通过传入email_address创建一行时,is_dangerous_token不是使用我编写的代码生成的。创建的行只有id,与accountis_dangerous_token的关系在数据库中没有值。 谢谢你的帮助

1 个答案:

答案 0 :(得分:1)

您必须在synonym列上使用account_email_address,因为您需要它来生成令牌:

class PassRecovery(DeclarativeBase):
    __tablename__ = 'pass_recoveries'

    id = Column(Integer, primary_key=True)
    _account_email_address = Column(Unicode(255), ForeignKey('accounts.email_address'), index=True)
    account = relationship('Account', backref=backref('pass_recoveries', cascade='all, delete-orphan'))
    is_dangerous_token = Column('is_dangerous_token', Unicode(255))

    def _set_account_email_address(self, account_email_address):
        self._account_email_address = account_email_address

        secret_key = config.get('is_dangerous_key')
        signer = TimestampSigner(secret_key)
        self.is_dangerous_token = signer.sign(self._account_email_address)

    def _get_account_email_address(self):
        return self.account_email_address

    account_email_address = synonym(
        '_account_email_address',
        descriptor=property(_get_account_email_address, _set_account_email_address)
    )

编辑1

假设Persoan.A是同义词。

session.query(Person).filter(Person.A > 8)

因此,您可以在查询中使用数据库中不存在的列来计算复杂表达式。

但你不能用属性来做这件事。在你的情况下,最好简单地使用python的属性而不是同义词,以避免sqlalchemy同义词的成本。

另一种方法是使用sqlalchemy events,监听更改属性,并在引发事件时执行任何操作。