如何在sqlalchemy中使用带过滤器的连接表上使用聚合函数?

时间:2017-01-16 17:02:40

标签: python join sqlalchemy aggregate-functions flask-sqlalchemy

我正在尝试从以下表中生成我想要与SQLALCHEMY(或文本SQL方法)连接的结果。

class Requisition(Base):
    __tablename__ = 'requisition'

    id = Column(Integer, primary_key=True)
    order_no = Column(Float)

class Budget(Base):
    __tablename__ = 'budget'

    id = Column(Integer, primary_key=True)
    budget_line = Column(String)
    amount = Column(Numeric(12,2))
    requisition_id = Column(Integer, ForeignKey('requisition.id'))
    requisition = relationship(Requisition)

我的目标是加入这些表,以便我可以通过requisition.order_no过滤联接的表,并返回由budget.budget_line分组的值和budget.amount的总和。我已经尝试了一百万种方法来写这个,我得到了各种各样的错误。这是我最近的尝试:

def sum_budgets_original_budget(current_order_no):
    budgets_query = session.query(Budget.budget_line, Requisition, func.sum(Budget.amount)).group_by(Budget.budget_line)\
       .filter(text("order_no<=:current_order_no")).params(current_order_no=current_order_no).all()
  return dict(budgets_query)

这是我得到的错误。 (我从上面的表中删除了几个不影响错误的不必要的列,但是你可以在异常响应中看到它们被引用。)

ProgrammingError :( ProgrammingError)column&#34; requisition.id&#34;必须出现在GROUP BY子句中或用于聚合函数LINE 1:SELECT budget.budget_line AS budget_budget_line,requisition ... ^&#39; SELECT budget.budget_line AS budget_budget_line,requisition.id AS requisition_id,requisition.order_no AS requisition_order_no,requisition.requisition_name AS requisition_requisition_name,requisition.created_date AS requisition_created_date,requisition.modified_date AS requisition_modified_date,requisition.subproject_id AS requisition_subproject_id,requisition.core_time_period AS requisition_core_time_period,sum(budget.amount)AS sum_1 \ nFROM预算,申请单\ nWHERHER budget.subproject_id =%(subproject_id_1)s AND budget.budget_transaction_type =%(budget_transaction_type_1)s AND order_no&lt; =%(current_order_no)s GROUP BY budget.budget_line&#39; {&#39; current_order_no&#39;:5,&#39; budget_transaction_type_1&#39;:&#39;原始预算&#39;,&#39; subproject_id_1&#39;:1}

1 个答案:

答案 0 :(得分:1)

请勿在您的选择列表中加入Requisition,但请明确加入。与text表达式相比,使用映射的类属性编写过滤谓词更整洁。

budgets_query = session.query(
    Budget.budget_line,
    func.sum(Budget.amount)
).\
    join(Requisition).\
    filter(Requisition.order_no <= current_order_no).\
    group_by(Budget.budget_line).\
    all()

如果您愿意,您也可以将关系Budget.requisition传递给join(),而不是实体。