【问题标题】:How to use aggregate functions on joined tables with filters in sqlalchemy?如何在 sqlalchemy 中使用带有过滤器的连接表上的聚合函数?
【发布时间】:2017-05-31 14:08:21
【问题描述】:

我正在尝试从我想与 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) 列“requisition.id”必须出现在 GROUP BY 子句中或用于聚合函数第 1 行:SELECT budget.budget_line AS budget_budget_line, requisition... ^ '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,总和(budget.amount)AS sum_1 \n从预算,申请 \nWHERE budget.subproject_id = %(subproject_id_1)s AND budget.budget_transaction_type = %(budget_transaction_type_1)s AND order_no

【问题讨论】:

  • 您能否告诉我们您遇到了哪些错误?
  • @WillemVanOnsem 好的。谢谢。

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


【解决方案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(),而不是实体。

【讨论】:

  • 你太棒了。像魅力一样工作。谢谢!
猜你喜欢
  • 2017-08-16
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
  • 2012-07-08
  • 2021-12-09
  • 2018-10-28
相关资源
最近更新 更多