【问题标题】:SQLAlchemy order by function resultSQLAlchemy 按函数结果排序
【发布时间】:2015-02-15 18:26:37
【问题描述】:

这是我拥有的代码,它正在运行(返回所有按难度排序的问题):

def get_noteworthy_problems(self):

    ACategory = aliased(Category)
    AProblem = aliased(Problem)

    all_prob = DBSession.query(AProblem).filter(
        AProblem.parent_id == ACategory.id,
        ACategory.parent_id == self.id)

    noteworthy_problems = \
        sorted(all_prob, key=lambda x: x.difficulty(), reverse=True)

    return noteworthy_problems

但我认为我必须优化这段代码。 是否有可能更改具有order_by 和我的函数difficulty() 的代码?我的函数返回一个数字。我试过类似的东西:

    result = DBSession.query(AProblem).filter(
        AProblem.parent_id == ACategory.id,
        ACategory.parent_id == self.id).order_by(
        AProblem.difficulty().desc())

但我收到错误TypeError: 'NoneType' object is not callable

【问题讨论】:

    标签: python sql sql-server sqlalchemy


    【解决方案1】:

    Hybrid attributes 是既充当 Python 属性又充当 SQL 表达式的特殊方法。只要你的difficulty函数可以用SQL表达,就可以像普通列一样进行过滤排序。

    例如,如果您将难度计算为问题的鹦鹉数量,如果问题超过 30 天,则乘以 10,您可以使用:

    from datetime import datetime, timedelta
    from sqlalchemy import Column, Integer, DateTime, case
    from sqlalchemy.ext.hybrid import hybrid_property
    
    class Problem(Base):
        parrots = Column(Integer, nullable=False, default=1)
        created = Column(DateTime, nullable=False, default=datetime.utcnow)
    
        @hybrid_property
        def difficulty(self):
            # this getter is used when accessing the property of an instance
            if self.created <= (datetime.utcnow() - timedelta(30)):
                return self.parrots * 10
    
            return self.parrots
    
        @difficulty.expression
        def difficulty(cls):
            # this expression is used when querying the model
            return case(
                [(cls.created <= (datetime.utcnow() - timedelta(30)), cls.parrots * 10)],
                else_=cls.parrots
            )
    

    并通过以下方式查询:

    session.query(Problem).order_by(Problem.difficulty.desc())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多