如何在SQLAlchemy中实现这个混合属性的SQL级表达式?

2024-09-27 21:24:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个分类账表和一个相应的python类。 我用SQLAlchemy定义了模型,如下所示:

class Ledger(Base):
    __tablename__ = 'ledger'

    currency_exchange_rate_lookup = {('CNY', 'CAD'): 0.2}

    amount = Column(Numeric(10, 2), nullable=False)
    currency = Column(String, nullable=False)
    payment_method = Column(String)
    notes = Column(UnicodeText)

    @hybrid_property
    def amountInCAD(self):
        if self.currency == 'CAD':
            return self.amount
        exchange_rate = self.currency_exchange_rate_lookup[(self.currency, 'CAD')]
        CAD_value = self.amount * Decimal(exchange_rate)
        CAD_value = round(CAD_value, 2)
        return CAD_value

    @amountInCAD.expression
    def amountInCAD(cls):
        amount = cls.__table__.c.amount
        currency_name = cls.__table__.c.currency
        exchange_rate = cls.currency_exchange_rate_lookup[(currency_name, 'CAD')]
        return case([
            (cls.currency == 'CAD', amount),
        ], else_ = round((amount * Decimal(exchange_rate)),2))

现在你可以看到一个叫做混合动力的房产。Python级别的getter似乎工作正常。但是SQL表达式不起作用。在

现在,如果我运行这样的查询:

^{pr2}$

SQLAlchemy给出了以下错误:

  File "ledger_db.py", line 43, in amountInCAD
    exchange_rate = cls.currency_exchange_rate_lookup[(currency_name, 'CAD')]
KeyError: (Column('currency', String(), table=<ledger>, nullable=False), 'CAD')

我研究了SQLAlchemy关于混合属性的在线文档。http://docs.sqlalchemy.org/en/latest/orm/mapped_sql_expr.html#using-a-hybrid 将我的代码与示例代码进行比较,我不明白为什么我的代码不起作用。如果在官方示例中,cls.firstname可以引用值列,为什么在我的代码中,cls.__table__.c.currency只返回一个Column而不是它的值?在


Tags: 代码selfrateexchangesqlalchemyvaluetablecolumn
1条回答
网友
1楼 · 发布于 2024-09-27 21:24:22

cls.firstname不是“引用值”,而是Columnexample中的{}生成一个字符串连接SQL表达式,其行如下: 在

firstname || ' ' || lastname

这是混合属性魔力的一部分:它们使编写可以在两个域中工作的简单表达式变得相对容易,但您仍然必须了解何时处理python实例以及何时构建SQL表达式。在

您可以重新考虑一下您自己的混合动力,并在case表达式中将转换选项传递给DB:

^{pr2}$

这样可以有效地将汇率查询作为CASE表达式传递给SQL。在

相关问题 更多 >

    热门问题