将带有JOIN ON的SQL查询转换为SQLAlchemy

7

我的查询看起来像这样(当然,在实际使用中,“3”和“4”将是不同的):

SELECT op_entries.*, op_entries_status.*
FROM op_entries
LEFT OUTER JOIN op_entries_status ON op_entries.id = op_entries_status.op_id AND op_entries_status.order_id = 3
WHERE op_entries.op_artikel_id = 4 AND op_entries.active
ORDER BY op_entries.id

获取订单/物品组合生产的所有阶段(操作)以及每个阶段的当前状态(进度),如果存在状态条目,则必须返回该状态,但状态行必须为空。

我在SQLAlchemy中遇到了很大的问题。这本来是一个两部分的问题,但是我已经在这里找到了用纯SQL实现的解决方法。现在在ORM中,这是一个不同的故事,我甚至无法通过文档弄清如何使用JOIN ON条件!

编辑(新用户不允许回答自己的问题):

我相信我解决了它,我想把它写下来作为一个问题帮助其他新手。也许这会对其他新手有所帮助。

query = db.session.query(OpEntries, OpEntriesStatus).\
    outerjoin(OpEntriesStatus, db.and_(
        OpEntries.id == OpEntriesStatus.op_id,
        OpEntriesStatus.order_id == arg_order_id)).\
    filter(db.and_(
        OpEntries.op_artikel_id == artidQuery,
        OpEntries.active)).\
    order_by(OpEntries.id).\
    all()

我将保持此处的开放,以便如果有更好的解决方案或任何见解时能及时补充。

1个回答

14
假设有一些命名规范,下面的代码应该可以实现:
qry = (session.query(OpEntry, OpEntryStatus)
        .join(OpEntryStatus, and_(OpEntry.id == OpEntryStatus.op_id, OpEntryStatus.order_id == 3))
        .filter(OpEntry.op_artikel_id == 4)
        .filter(OpEntry.active == 1)
        .order_by(OpEntry.id)
        )

阅读join,outerjoin以获取有关连接的更多信息,其中第二个参数是onclause。如果您需要多个,请使用and_or_创建所需的任何表达式。


谢谢!在这种情况下,需要使用外连接,但除此之外,我认为它看起来很好。不过我没有测试过。如果我抢了你的风头,对不起。 - not amused
链接已失效。也许应该更改为http://docs.sqlalchemy.org/en/latest/orm/join_conditions.html? - Jesse Aldridge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接