【问题标题】:Sqlalchemy order by calculated column按计算列排序的 Sqlalchemy
【发布时间】:2013-06-06 15:29:05
【问题描述】:

我正在尝试使用 sqlalchemy 构建一个选择查询,但我需要按计算值对结果进行排序,但我不知道该怎么做。

基本上,我有一个 'start_time' 和 'end_time' 列,我想根据 start_time 和 end_time 对结果进行排序,但是如果 end_time

end_time + (86400000 if end_time < start_time else 0)

我不知道该怎么做。是否有任何简单的方法可以将计算属性添加到我的表类并让查询检索该属性?

我尝试使用 @property 为计算的 end_time 创建一个 getter,但没有成功。

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    首先,您需要定义将包含实现为 sql 函数的公式的列

    比您使用定义的列构建查询:

    col = tclass.end_time + case([(tclass.end_time<tclass.start_time, 86400000)], else_=0 )
    q = session.query(col).order_by(col)
    print q
    

    还有一种方法可以将这样的计算列添加到映射对象类定义中:

    class TName(Base):
        end_time = Column(Integer)
        start_time = Column(Integer)
        calc_column = end_time + case([(end_time<start_time, 86400000)], else_=0 )
    
    q2 = session.query(TName.calc_column).order_by(TName.calc_column)
    

    【讨论】:

    • 这确实有效,但有没有办法将计算属性添加到我的表中,以便查询始终检索它?请注意,此属性不应存储在数据库中。
    • 这也适用于 SQLAlchemy - 请参阅我的答案的更新
    • 如此简单优雅!惊人! 10x
    • 如果计算的值依赖于某个变量(并且不仅仅在其他列上计算)怎么办?
    • 我通过here问了一个关于同一问题的变体的问题
    【解决方案2】:

    sqlalchemy documentation 现在似乎建议使用混合来执行此操作。

    例子:

    from sqlalchemy.ext.hybrid import hybrid_property
    
    class Tname(Base):
        end_time = Column(Integer)
        start_time = Column(Integer)
    
        @hybrid_property
        def calc_column(self):
            if self.end_time < self.start_time:
                return self.end_time + 86400000 
            else: 
                return self.end_time
    

    然后你可以运行一个典型的查询并按 calc_column 排序。

    【讨论】:

    • 计算是在数据库内部完成,还是在 Python 应用程序代码中完成?如果在 Python 中,这可能涉及通过网络对大量数据进行改组,这可以通过在 DB 内部进行计算来避免(例如,在 WHERE 子句中使用 calc_column 时)。
    • 如果为属性指定表达式,它将用于计算数据库端的值,否则在 Python 中。
    猜你喜欢
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    相关资源
    最近更新 更多