Ответ 1
Это должно работать:
(session.query(A)
.join(B, A.some_field == B.some_other_field)
.outerjoin(C, A.some_field == C.some_different_field)
.add_entity(B)
.add_entity(C))
Я использую ORM-сопоставление в SQLAlchemy 0.6.8.
У меня есть три таблицы (A, B и C), без внешних ключей между ними.
Я пытаюсь присоединиться к таблицам A и B, а затем оставил внешнее объединение, что с C. Я ожидаю, что именованный кортеж с полями A, B и C - с полем C иногда устанавливается None.)
Я могу сделать первое соединение достаточно легко, просто выбрав обе таблицы.
(session.query(A, B)
.filter(A.some_field = B.some_other_field))
Это дает мне NamedTuple с полями A и B.
Затем я добавляю внешнее соединение, чтобы сделать это:
(session.query(A, B)
.filter(A.some_field==B.some_other_field))
.outerjoin((C, A.some_field==C.some_different_field))
В результате все еще есть две таблицы. Я не могу получить доступ к другим полям C (даже в тех случаях, когда они присутствуют).
Каков правильный способ сделать левое внешнее соединение, чтобы получить доступ к полям самой правой таблицы?
Я бы предпочел не возвращаться к базовому SQL, если бы мог это избежать - я пытаюсь научиться использовать ORM.
Это должно работать:
(session.query(A)
.join(B, A.some_field == B.some_other_field)
.outerjoin(C, A.some_field == C.some_different_field)
.add_entity(B)
.add_entity(C))
Ориентировочный ответ на мой собственный вопрос:
Этот код, как представляется, генерирует SQL, который я хочу:
(session.query(A, B, C)
.filter(A.some_field==B.some_other_field))
.outerjoin((C, A.some_field==C.some_different_field))
Обратите внимание на добавление параметра C к исходному вызову session.query
.
Это не похоже на то, что я думал, что это будет делать: A, соединенный с B, соединенным с C слева, снова соединенным с C.
Я все еще тестирую.