如何将十进制和字符串格式化为混合表达式的一部分?

2024-09-30 03:22:06 发布

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

问题:

我创建了一个混合属性,它由一个字符串和一个按百分比格式化的十进制组成,但是在使用混合表达式时,我得到了一个TypeError。我尝试了f字符串的几种变体,包括首先将其转换为float,但在同一行中仍然出现错误。在混合属性表达式上进行字符串格式化和连接的最佳方法是什么

我想知道为什么“result_1”产生错误,“result_2”工作正常

模型

from decimal import Decimal as D
class SupplierDiscount(Base):
    __tablename__ = "tblSupplierDiscount"
    id = Column(Integer, primary_key=True)
    discount = Column(DECIMAL(5, 4), nullable=False)
    description = Column(String, nullable=False)
    
    
    @hybrid_property
    def disc_desc(self):
        return f'{self.description}: {self.discount * 100:.4f}%'


    @disc_desc.expression
    def disc_desc(cls):
        return f'{cls.description}: {cls.discount * 100:.4f}%' # Error generated here

结果_1-首选方法-但会导致错误

result_1 = session.query(SupplierDiscount.id.label("SDId"),
                         SupplierDiscount.disc_desc.label("SDDDesc")
                         ).all()
print('Below is from result_1')
print(result_1)
for i in result_1:
    print(i.id, i.disc_desc)

结果_1中产生错误

TypeError: unsupported format string passed to BinaryExpression.__format__

结果_2-该方法可行,但不是首选方法

result_2 = session.query(SupplierDiscount).all()
print('Below is from result_2')
print(result_2)
for i in result_2:
    print(i.id, i.disc_desc)

环境

SQLAlchemy==1.3.20
PostgreSQL 13

Tags: 方法字符串fromselfid错误columndiscount
1条回答
网友
1楼 · 发布于 2024-09-30 03:22:06

类级访问和实例级访问之间存在区别。hybrid属性用于实例级别,并使用python字符串格式来获得所需的结果。由于表达式用于类级访问,因此需要将其定义为SQL表达式以返回所需的结果。请参阅^{}以获取参考

知道了这一点,我们可以将代码重写为以下内容,以在类级别和实例级别获得相同的结果:

from sqlalchemy import Column, Integer, create_engine, DECIMAL, String, func
from sqlalchemy.engine import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import Session

Base = declarative_base()

class Discount(Base):
    __tablename__ = 'Discount'
    id = Column(Integer, primary_key=True)
    description = Column(String)
    discount = Column(DECIMAL(5,4))

    @hybrid_property
    def disc_desc(self):
        return f'{self.description}: {self.discount * 100:.4f}%'

    @disc_desc.expression
    def disc_desc(cls):
        return cls.description + ' ' + func.cast(cls.discount * 100, String) + '%'


engine = create_engine(dburl)

Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)

with Session(engine) as session:
    discount = Discount(description='test', discount=5.4)

    session.add(discount)
    session.commit()

    disc = session.query(Discount).first()
    print('Instance-level access')
    print(disc.disc_desc)
    print('')

    disc = session.query(Discount.disc_desc).first()
    print('Class-level access')
    print(disc.disc_desc)

这导致:

Instance-level access
test: 540.0000%

Class-level access
test: 540.0000%

相关问题 更多 >

    热门问题