鉴于此FromClause
:
q = (
select([Review, Photo])
.select_from(
outerjoin(Review, Photo, false())
).apply_labels()
).union_all(
select([Review, Photo])
.select_from(
outerjoin(Photo, Review, false())
).apply_labels()
)
我可以通过以下方式选择orm中的对象:
s.query(Review, Photo).select_entity_from(q).all()
给出结果:
[(Review(id=1, thing_id=100, ...), None),
(Review(id=2, thing_id=100, ...), None),
(Review(id=3, thing_id=101, ...), None),
(None, Photo(id=1, thing_id=100))]
我想将此加入我的Thing
表格,以便:
[(Thing(100), Review(id=1, thing_id=100, ...), None),
(Thing(100), Review(id=2, thing_id=100, ...), None),
(Thing(101), Review(id=3, thing_id=101, ...), None),
(Thing(100), None, Photo(id=1, thing_id=100)),
(Thing(102), None, None)]
然而,当我尝试:
thing_q = select([Thing, Review, Photo]).select_from(
outerjoin(Thing, q,
(Review.thing_id == Thing.id) |
(Photo.thing_id == Thing.id)
)
)
发出的查询是:
SELECT
things.id, things....,
-- this should be selecting these from the subquery...
reviews.id, reviews.thing_id, reviews....,
photos.id, photos.thing_id, photos....,
FROM
reviews, -- not from the tables, doing a CROSS JOIN!
photos, -- Look, another CROSS JOIN!
things
LEFT OUTER JOIN (
SELECT
reviews.id AS reviews_id,
reviews.thing_id AS reviews_thing_id,
reviews.... as reviews_...,
photos.id AS photos_id,
photos.thing_id AS photos_thing_id
photos.... as photos...,
FROM
reviews
LEFT OUTER JOIN photos ON 0
UNION ALL
SELECT
reviews.id AS reviews_id,
reviews.thing_id AS reviews_thing_id,
reviews.... as reviews_...,
photos.id AS photos_id,
photos.thing_id AS photos_thing_id
photos.... as photos...,
FROM
photos
LEFT OUTER JOIN reviews ON 0
) ON reviews.thing_id = things.id OR photos.thing_id = things.id
已经进行了交叉加入!如何从Review
条款中选择Photo
和UNION ALL
?
thing_q = s.query(Thing, Review, Photo).select_entity_from(
outerjoin(Thing, q,
(Review.thing_id == Thing.id) |
(Photo.thing_id == Thing.id)
)
)
给出了:
File "...\sqlalchemy\lib\sqlalchemy\sql\compiler.py", line 1397, in visit
translate_dict[right.element.left] = selectable_
AttributeError: 'CompoundSelect' object has no attribute 'left'
是的,神秘的错误。不知道我在这里做错了什么。
答案 0 :(得分:0)
尝试使用Query.add_entity()
,因为它会将Thing
放在最右边。以下代码段可能适用于您:
>>> query = session.query(Review, Photo).select_entity_from(q)
>>> query = query.add_entity(Thing)
>>> query = query.join(Thing,
... (Thing.id == Review.thing_id) |
... (Thing.id == Photo.thing_id))
>>> print query.first() # Just an expectation...
(Review(id=1, thing_id=100, ...), None, Thing(100))