2012-07-09 97 views
6

我有兩個表beardmoustache定義如下:RIGHT OUTER JOIN在SQLAlchemy的

+--------+---------+------------+-------------+ 
| person | beardID | beardStyle | beardLength | 
+--------+---------+------------+-------------+ 

+--------+-------------+----------------+ 
| person | moustacheID | moustacheStyle | 
+--------+-------------+----------------+ 

我已PostgreSQL中創建的SQL查詢,這將結合這兩個表,併產生如下結果:

+--------+---------+------------+-------------+-------------+----------------+ 
| person | beardID | beardStyle | beardLength | moustacheID | moustacheStyle | 
+--------+---------+------------+-------------+-------------+----------------+ 
| bob | 1  | rasputin | 1   |    |    | 
+--------+---------+------------+-------------+-------------+----------------+ 
| bob | 2  | samson  | 12   |    |    | 
+--------+---------+------------+-------------+-------------+----------------+ 
| bob |   |   |    | 1   | fu manchu  | 
+--------+---------+------------+-------------+-------------+----------------+ 

查詢:

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" 

但是我無法創建它的SQLAlchemy表示形式。我嘗試了幾種實施from_statementouterjoin的方法,但沒有一個真正起作用。任何人都可以幫助我嗎?

+0

什麼是「ON」條款意思? – 2012-07-09 17:50:51

+0

它沒有檢查執行'加入' – 2012-07-09 17:52:47

+0

爲什麼你想要以這種格式表示結果而不是'Person'類和兩個關係'Person.beards'和'Person.mustashes'?基本上我的問題是:爲什麼使用'sqlalchemy'來做'SQL'這樣的事情?如果你定義了關係,你可以發出'session.query(Person).options(joinedload('beards'))選項(joinedload('mustashes'))。all()',並且生成的查詢將會非常相似,但結果仍然是'Person'的一個實例,而不是'tuple'。 – van 2012-07-09 21:54:35

回答

2

@Francis Psuggestion我想出了這個片斷:

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() 

但是這個工作,但你不能把它作爲一個答案因爲它看起來像一個黑客。這是sqlalchemy中應該有RIGHT OUTER JOIN的另一個原因。

-1

爲什麼不利用這個簡單的查詢:

SELECT person, beardID, beardStyle, beardLength, 
     NULL AS moustacheID, NULL AS moustacheStyle 
FROM beards 
WHERE person = "bob" 

UNION 

SELECT person, NULL AS beardID, NULL AS beardStyle, NULL AS beardLength, 
     moustacheId, moustacheStyle 
FROM mustaches 
WHERE person = "bob" 
+2

此處的問題不是寫它的SQL查詢。它在於如何使SQLAlchemy表示它。即使你給出的答案在SQLAlchemy中編寫也很棘手。如果你能夠在SQLAlchemy中編寫它,那將會很棒。 – 2012-07-09 18:12:48

+1

是有幫助的嗎? http://stackoverflow.com/questions/7971798/sqlalchemy-union-with-different-number-of-columns – 2012-07-09 18:16:29

+0

是的,這是有幫助的。謝謝:) – 2012-07-10 09:57:05

1

下面是我得到了什麼,ORM風格:

from sqlalchemy.sql import select, false 

stmt = (
    select([Beard, Moustache]) 
    .select_from(
     outerjoin(Beard, Moustache, false()) 
    ).apply_labels() 
).union_all(
    select([Beard, Moustache]) 
    .select_from(
     outerjoin(Moustache, Beard, false()) 
    ).apply_labels() 
) 

session.query(Beard, Moustache).select_entity_from(stmt) 

這似乎是在它自己的工作,但似乎是不可能與另一個選擇表達加入

+0

何時應該使用這種風格('select')而不是「正常」的方式('session.query')? – 2016-09-11 04:15:35

+0

@MatthewMoisen:據我所知,你不能在from子句中放置'.query'。 – Eric 2016-09-11 04:34:07