Я использую SQLAlchemy с Pyramid. Я пытаюсь выполнить запрос с пользовательским условием соединения:
DBSession.query(A)\
.outerjoin(A.b, B.a_id == A.id)\
.all();
Однако запрос не может выполнить следующую ошибку:
AttributeError: Ни объект «BinaryExpression», ни объект «Comparator» не имеют атрибута «выбираемый»
Проблема проистекает из условия, как будто я его удаляю, запрос работает:
DBSession.query(A)\
.outerjoin(A.b)\
.all();
Я не понимаю проблему, поскольку следую синтаксису, описанному в документация:
q = session.query (Пользователь) .join (Адрес, User.id == Address.user_id)
Кто-нибудь видит, что происходит?
3 ответа
Хорошо, я видел это. Если вы добавите пользовательское условие, синтаксис будет не .outerjoin(A.b, ...)
, а .outerjoin(B, ...)
Они должны принять оба, на самом деле
(и сообщение об ошибке может быть немного более явным)
Другая возможная причина этой ошибки - неправильное использование явного предложения ON для join()
: явное предложение 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 сам по себе очень подробный, но несколько суммированный (в нем говорится, что 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
могут быть не только классами сопоставления, но и чем-либо «выбираемым»:subquery()
, экземпляромTable
или псевдонимом ({{ X4}}) подойдет. - без явного предложения ON
A
иB
могут быть только классом отображения или экземпляромTable
Еще один способ сказать, что если вы уже указали отношение через .outerjoin(A.b...
, вам больше не нужно указывать условие, и фактически вы не можете выполнить и то, и другое.
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.