如何从 SQLAlchemy JOIN 中的两个表返回结果?

Posted

技术标签:

【中文标题】如何从 SQLAlchemy JOIN 中的两个表返回结果?【英文标题】:How do I return results from both tables in a SQLAlchemy JOIN? 【发布时间】:2013-12-19 21:17:42 【问题描述】:

我在我的 ORM 中定义了两个表:

Base = declarative_base()

class GeneralLedger(Base):
  __tablename__ = 'generalledgers'
  id = Column(Integer, primary_key=True)
  invoiceId = Column(Integer)
  ..

class ConsolidatedLedger(Base):
  __tablename__ = 'consolidatedledgers'
  id = Column(Integer, primary_key = True)
  invoiceId = Column(Integer)

..

我没有在两个表之间设置任何关系。我按如下方式加入:

records = DBSession.query(GeneralLedger).join(ConsolidatedLedger, GeneralLedger.invoiceId == ConsolidatedLedger.invoiceId).all()

我也试过了:

records = DBSession.query(GeneralLedger).filter(GeneralLedger.invoiceId == ConsolidatedLedger.invoiceId).all()

在这两种情况下,当我在视图中显示结果时,只会显示 GeneralLedger 表中的条目。如何从同一结果集中的两个表中获取结果?我试过这个:

records = DBSession.query(GeneralLedger, ConsolidatedLedger).join(ConsolidatedLedger, GeneralLedger.invoiceId == ConsolidatedLedger.invoiceId).all()

但是,由于某种原因,当我遍历模板 (Jinja2) 中的结果时,每一行的列值都是空的。另外,当计数时:

total = DBSession.query(GeneralLedger).join(ConsolidatedLedger, GeneralLedger.invoiceId == ConsolidatedLedger.invoiceId).count()

总行数是两个表中匹配记录的总和。我正在使用 webhelpers.paginate 来处理分页:

query = DBSession.query(GeneralLedger).join(ConsolidatedLedger, GeneralLedger.invoiceId == ConsolidatedLedger.invoiceId)
records = paginate.Page(query, current_page, url=page_url)

并且发送到模板的结果集就好像除 ConslidatedLedger 表上的结果之外的所有结果都已删除。例如,我将页面总数设置为 20 条记录。如果该页面上有来自 ConslidatedLedger 的记录,则该页面将被截断,仅显示来自 GeneralLedger 的记录,但分页并未中断。

有什么想法吗?谢谢!

【问题讨论】:

【参考方案1】:
records = DBSession.query(GeneralLedger, ConsolidatedLedger).join(ConsolidatedLedger, GeneralLedger.invoiceId == ConsolidatedLedger.invoiceId).all()

应该可以,但我认为在使用记录集时,您需要通过records.GeneralLedgerrecords.ConsolidatedLedger 引用它们:

for record in records:
    print record.GeneralLedger
    print record.ConsolidatedLedger

    print record.GeneralLedger.foo
    # ...etc

【讨论】:

这行得通,但我认为我的用例只需要 GeneralLedger 数据库中的记录。有没有办法可以查询(GeneralLedger).join(...)?如果我执行原始查询记录 = DBSession.query(GeneralLedger).join(ConsolidatedLedger, GeneralLedger.invoiceId == ConsolidatedLedger.invoiceId).all() 我只从表 generalledgers 中获取项目,但分页认为所有项目都在那里并且count() 也可以。我怎样才能摆脱 conslidatedledgers 表中的项目? 嗯,我不熟悉分页过程。控制台日志是否显示生成的 SQL 查询,GeneralLedger 和 ConsolidatedLedger 之间是否存在一对多关系?如果 GeneralLedger 记录有多个 ConsolidatedLedger,我会看到重复的结果。您可以尝试使用 .distinct() 而不是 .all(),如果可以编译 ID 列表而不是 join,并检查该列表是否包含您的 GeneralLedger ID?

以上是关于如何从 SQLAlchemy JOIN 中的两个表返回结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Yii2中的left join从两个表中获取所有列数据

尝试在 sqlalchemy orm 查询中加入两个表,出现错误

如何在 Sqlalchemy ORM 中检查表中两个特定字段中的至少一个是不是为 NOT NULL? [复制]

如何从 sqlalchemy 中的 session/engine/meta 获取表名及其数据类型?

按 sqlalchemy 中的连接别名排序

进行联接时如何更改 SqlSoup / SqlAlchemy 中的 FROM 子句?