SQLAlchemy - condition on join fails with AttributeError: Neither 'BinaryExpression' object nor 'Comparator' object has an attribute 'selectable'
SQLAlchemy - condition on join fails with AttributeError: Neither 'BinaryExpression' object nor 'Comparator' object has an attribute 'selectable'
我运行正在使用 Pyramid 使用 SQLAlchemy。我正在尝试 运行 具有自定义 'join' 条件的查询:
DBSession.query(A)\
.outerjoin(A.b, B.a_id == A.id)\
.all()
但是查询失败并出现以下错误:
AttributeError: Neither 'BinaryExpression' object nor 'Comparator' object has an attribute 'selectable'
问题源于条件,如果我删除它,查询有效:
DBSession.query(A)\
.outerjoin(A.b)\
.all()
我不明白这个问题,因为我遵循 the documentation 中描述的语法:
q = session.query(User).join(Address, User.id==Address.user_id)
有人看到发生了什么事吗?
好的,我看到了。
如果添加自定义条件,则语法不是 .outerjoin(A.b, ...)
,而是 .outerjoin(B, ...)
他们应该都接受,真的
(错误信息可能稍微更明确)
另一种说法是,如果您已经通过 .outerjoin(A.b...
指定了关系,则不再需要指定条件,实际上不能同时指定。
此错误的另一个可能原因是 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 子句的
A
和 B
不仅可以是映射器 classes,还可以是任何 "selectable": subquery()
实例Table
或别名 (aliased(selectable)
) 即可。
- 没有明确的 ON 子句
A
和 B
只能是映射器 class 或 Table
实例
我运行正在使用 Pyramid 使用 SQLAlchemy。我正在尝试 运行 具有自定义 'join' 条件的查询:
DBSession.query(A)\
.outerjoin(A.b, B.a_id == A.id)\
.all()
但是查询失败并出现以下错误:
AttributeError: Neither 'BinaryExpression' object nor 'Comparator' object has an attribute 'selectable'
问题源于条件,如果我删除它,查询有效:
DBSession.query(A)\
.outerjoin(A.b)\
.all()
我不明白这个问题,因为我遵循 the documentation 中描述的语法:
q = session.query(User).join(Address, User.id==Address.user_id)
有人看到发生了什么事吗?
好的,我看到了。
如果添加自定义条件,则语法不是 .outerjoin(A.b, ...)
,而是 .outerjoin(B, ...)
他们应该都接受,真的
(错误信息可能稍微更明确)
另一种说法是,如果您已经通过 .outerjoin(A.b...
指定了关系,则不再需要指定条件,实际上不能同时指定。
此错误的另一个可能原因是 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 子句的
A
和B
不仅可以是映射器 classes,还可以是任何 "selectable":subquery()
实例Table
或别名 (aliased(selectable)
) 即可。 - 没有明确的 ON 子句
A
和B
只能是映射器 class 或Table
实例