SQLAlchemy - 连接条件因AttributeError而失败:“BinaryExpression”对象和“Comparator”对象都没有属性“selectable”

时间:2015-12-15 13:50:30

标签: python sqlalchemy pyramid

我正在使用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)

有谁看到发生了什么?

3 个答案:

答案 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)

在以上所有示例中,除了第一个示例:

    带有显式ON子句的
  • AB不仅可以是映射器类,还可以是任何“可选择的”类:subquery()Table的实例或别名(aliased(selectable))可以。
  • 没有显式ON子句AB只能是一个映射器类或Table实例