Nih*_*ant 8 python sql sqlalchemy
我有两个表beard,moustache定义如下:
+--------+---------+------------+-------------+
| person | beardID | beardStyle | beardLength |
+--------+---------+------------+-------------+
+--------+-------------+----------------+
| person | moustacheID | moustacheStyle |
+--------+-------------+----------------+
Run Code Online (Sandbox Code Playgroud)
我在PostgreSQL中创建了一个SQL查询,它将组合这两个表并生成以下结果:
+--------+---------+------------+-------------+-------------+----------------+
| person | beardID | beardStyle | beardLength | moustacheID | moustacheStyle |
+--------+---------+------------+-------------+-------------+----------------+
| bob | 1 | rasputin | 1 | | |
+--------+---------+------------+-------------+-------------+----------------+
| bob | 2 | samson | 12 | | |
+--------+---------+------------+-------------+-------------+----------------+
| bob | | | | 1 | fu manchu |
+--------+---------+------------+-------------+-------------+----------------+
Run Code Online (Sandbox Code Playgroud)
查询:
SELECT * FROM beards LEFT OUTER JOIN mustaches ON (false) WHERE person = "bob"
UNION ALL
SELECT * FROM beards b RIGHT OUTER JOIN mustaches ON (false) WHERE person = "bob"
Run Code Online (Sandbox Code Playgroud)
但是我无法创建它的SQLAlchemy表示.我尝试了几种方法from_statement,outerjoin但实际上没有一种方法可行.任何人都可以帮助我吗?
Tim*_*mur 10
在 SQL 中,A RIGHT OUTER JOIN B相当于B LEFT OUTER JOIN A. 因此,从技术上讲,RIGHT OUTER JOINAPI 中不需要- 可以通过切换目标“可选”和加入“可选”的位置来做同样的事情。SQL Alchemy 为此提供了一个 API:
# this **fictional** API:
query(A).join(B, right_outer_join=True) # right_outer_join doesn't exist in SQLA!
# can be implemented in SQLA like this:
query(A).select_entity_from(B).join(A, isouter=True)
Run Code Online (Sandbox Code Playgroud)
请参阅 SQLA Query.join() 文档,“控制要加入的内容”部分。
根据@Francis P的建议,我想出了这个片段:
q1 = session.\
query(beard.person.label('person'),
beard.beardID.label('beardID'),
beard.beardStyle.label('beardStyle'),
sqlalchemy.sql.null().label('moustachID'),
sqlalchemy.sql.null().label('moustachStyle'),
).\
filter(beard.person == 'bob')
q2 = session.\
query(moustache.person.label('person'),
sqlalchemy.sql.null().label('beardID'),
sqlalchemy.sql.null().label('beardStyle'),
moustache.moustachID,
moustache.moustachStyle,
).\
filter(moustache.person == 'bob')
result = q1.union(q2).all()
Run Code Online (Sandbox Code Playgroud)
然而,这可行,但你不能将其称为答案,因为它看起来像一个黑客。这是 sqlalchemy 中应该存在的又一个原因RIGHT OUTER JOIN。