2014-12-17 2 views
3

Это код, у меня есть, и он работает (возвращает все проблемы, заказанные трудом):SQLAlchemy заказ по функции результата

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.

ответ

4

Hybrid attributes - специальные методы, которые действуют как свойство Python, так и выражение SQL. Пока ваша функция difficulty может быть выражена в SQL, ее можно использовать для фильтрации и упорядочивания, как обычный столбец.

Например, если подсчитать трудности, как количество попугаев проблема имеет, раз десять, если проблема старше 30 дней, вы будете использовать:

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()) 
+1

Могут ли методы с гибридным дескриптором иметь аргументы? – user2290820

Смежные вопросы