简体   繁体   English

Python Camelot / sqlalchemy:在Select上执行数学运算

[英]Python Camelot/sqlalchemy: performing math on Select

I'm using Python Camelot, which uses sqlalchemy and sqlite under the hood. 我正在使用Python Camelot,它在后台使用sqlalchemy和sqlite。 I am storing hours as an integer to avoid floating point errors. 我将小时数存储为整数以避免浮点错误。 For example, 1 hour is stored in the database as 100, 2.5 hours is stored as 250, and so on. 例如,数据库中将1小时存储为100,将2.5小时存储为250,依此类推。 When I display hours, I want it to be divided by 100.0. 当我显示小时数时,我希望将其除以100.0。 Here's the code: 这是代码:

class Task( Entity ):
    __tablename__ = 'task'
    id = Column( Integer, primary_key=True )
    text = Column( String, nullable=False )
    completed = Column( Boolean, default=False )
    date_created = Column( Date, default=datetime.today )
    date_completed = Column( Date )
    notes = Column( String )

    @property
    def total_hours_estimated (self):
        value = sum([ work.hours_estimated for work in self.work ])
        value = value / 100.0
        return value

    @ColumnProperty
    def total_hours_estimated_colprop (self):
        return sql.select( [sql.func.sum(Work.hours_estimated)],
            Work.task_id == self.id)

class Work( Entity ):
    __tablename__ = 'work'
    id = Column( Integer, primary_key=True )
    date = Column( Date )
    hours_estimated = Column( Integer, default=0 )
    hours_actual = Column( Integer, default=0 )

    task_id = Column( Integer, ForeignKey('task.id') )
    task = relationship(Task, backref='work')

The @property approach calculates the desired result, but when viewed in the Camelot table it doesn't allow you to sort by that column. @property方法可以计算出所需的结果,但是在Camelot表中查看时,它不允许您按该列进行排序。 The docs say you have to use the ColumnProperty approach, but I can't figure out where to divide in the ColumnProperty approach. 文档说您必须使用ColumnProperty方法,但是我不知道在ColumnProperty方法中应该在哪里划分。 Is it possible? 可能吗?

Edit : It seems the issue is if I add in a float division, the sql.select is giving back Decimal objects, and maybe Camelot isn't liking that. 编辑 :似乎问题是,如果我添加一个浮点除法,则sql.select会返回Decimal对象,也许Camelot不喜欢那样。 Example: 例:

>>> session.query(sql.select( [sql.func.sum(Work.hours_estimated/100.0)])).all()
[(Decimal('5.5000000000'),)]

This is because the SQLAlchemy introspection is not able to exactly know the return type when some math is involved, in this case, it's probably the precision of the result that is unknown, so you have to help it a bit. 这是因为当涉及到某些数学运算时,SQLAlchemy内省不能完全知道返回类型,在这种情况下,结果的精度可能是未知的,因此您必须有所帮助。 This can be don through the field attributes : 这可以通过field属性来实现:

class Task(Entity):
    ...
    class Admin(EntityAdmin):
        list_display = ['id', 'text', 'total_hours_estimated_colprop']
        field_attributes = {
            'total_hours_estimated_colprop': {'delegate':delegates.FloatDelegate',
                                              'precision': 3} }

This forces displaying the result as float with precision 3. 这会强制将结果显示为精度为3的float。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM