0

Problem

I want to create a hybrid property which is composed of a string and a decimal formatted as percentage string but I am getting a TypeError. I've tried several variations on the f-string including converting it to float first but I still get the error on the same line. What is the best way to do this string formatting and concatenation on the hybrid property expression?

TypeError

Exception has occurred: TypeError
conversion from InstrumentedAttribute to Decimal is not supported

SQLAlchemy Model

from decimal import Decimal as D
class SupplierDiscount(Base):
    __tablename__ = "tblSupplierDiscount"
    __table_args__ = (UniqueConstraint('supplier_id', 'subProduct_id',
                                    'description', 'discount', 'dateEffStart',
                                    name='supplierDiscount_uc'), 
                                    {'schema': 'management'})
    id = Column(Integer, primary_key=True, unique=True, nullable=False)
    supplier_id = Column(Integer, ForeignKey(
        'management.tblSupplier.id'), nullable=False)
    subProduct_id = Column(Integer, ForeignKey(
        'management.tblSubProduct.id'), nullable=False)
    discount = Column(DECIMAL(5, 4), nullable=False)
    description = Column(String, nullable=False)
    dateEffStart = Column(DateTime, default=datetime.utcnow, nullable=False)
    dateEffEnd = Column(DateTime)
    isactive = Column(Boolean, nullable=False, default=1)
    supplier = relationship(
        'Supplier', foreign_keys=[supplier_id])
    subProduct = relationship(
        'SubProduct', foreign_keys=[subProduct_id])

    
    @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
        # Exception has occurred: TypeError
        # conversion from InstrumentedAttribute to Decimal is not supported

Environment

SQLAlchemy==1.3.20
PostgreSQL 13

Might be related Question

I have opened up another question here, but I am not sure if these two are related.

aik3e
  • 131
  • 6
  • `self.discount` is a `Decimal` so you don't have to cast is again. Using `return f'{self.description}: {self.discount:.4f}%'` should work! – rfkortekaas Mar 26 '21 at 12:25
  • Thanks @rfkortekaas. I have edited the code as you suggested (also added the *100). I now think that the issue is in the way I am querying the data. I have opened up another question [here](https://stackoverflow.com/questions/66827765/what-is-the-difference-in-sqlalchemy-query-using-whole-table-vs-specific-column). Can you please have a look, maybe you can help? – aik3e Mar 27 '21 at 03:38
  • 1
    @rfkortekaas, what is the best way to convert the code you have provided from the '@hybrid_property' instance level to the class level '@hybrid_property.expression'? – aik3e Mar 29 '21 at 00:45

0 Answers0