我正在使用Pyramid运行SQLAlchemy。我正在尝试使用自定义“加入”条件运行查询:
DBSession.query(A)\
.outerjoin(A.b, B.a_id == A.id)\
.all();
然而查询失败了以下错误:
AttributeError:'BinaryExpression'对象和'Comparator'对象都没有属性'selectable'
问题源于条件,就像我删除它一样,查询有效:
DBSession.query(A)\
.outerjoin(A.b)\
.all();
我不理解这个问题,因为我遵循the documentation中描述的语法:
q = session.query(User).join(Address,User.id == Address.user_id)
有谁看到发生了什么?
答案 0 :(得分:13)
好的,我看到了。
如果您添加自定义条件,则语法不是.outerjoin(A.b, ...)
,而是.outerjoin(B, ...)
他们应该接受这两个,真的
(错误消息可能有点更明确)
答案 1 :(得分:0)
另一种说法是,如果您已经通过.outerjoin(A.b...
指定了关系,则不再需要指定条件,实际上不能同时指定两者。
答案 2 :(得分:0)
此错误的另一个可能原因是join()
对显式ON子句的错误使用:显式ON子句应为单个表达式。因此,如果您打算在ON子句中使用多个过滤器,则应将它们与and_
/ or_
结合使用。例如,如果您想在ON子句中为联接添加其他条件:
query(A).join(B, A.b_id = B.id, A.x > N) # WRONG!
query(A).join(B, and_(A.b_id = B.id, A.x > N)) # CORRECT
Query.join() SQLA API doc本身非常详细,但摘要中有些含糊(表示join(*args, **kwargs)
并没有多大帮助)。以下是Query.join()
正确使用的一些一些摘要:
# declare the join using own field which leads to the related object:
query(A).join(A.b)
# declare the join using a class of the related mapper:
query(A).join(B)
# same as above (using related mapper class) but use explicit ON clause
# ON clause can be any/"complex" expression
query(A).join(B, A.b_id = B.id)
query(A).join(B, _and(A.b_id = B.id, ...))
# reverse the order of the join (useful to do a right outer join for example):
query(A).select_entity_from(B).join(A, isouter=True)
在以上所有示例中,除了第一个示例:
A
和B
不仅可以是映射器类,还可以是任何“可选择的”类:subquery()
,Table
的实例或别名(aliased(selectable)
)可以。 A
和B
只能是一个映射器类或Table
实例