2012-07-09 17 views
6

że dwie tabele beard i moustache zdefiniowano poniżej:prawe sprzężenie zewnętrzne w SQLAlchemy

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

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

Utworzono wysłania zapytania w PostgreSQL, które łączą te dwa stoły i generować następujące wyniki:

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

Zapytanie:

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" 

Jednak nie mogę utworzyć reprezentacji SQLAlchemy. Próbowałem na kilka sposobów, od wykonania from_statement do outerjoin, ale żaden z nich naprawdę nie działał. Czy ktoś może mi w tym pomóc?

+0

co to „ON” klauzuli oznaczać? –

+0

nie wykonuje sprawdzenia dla implementacji 'join' –

+0

Dlaczego chcesz, aby wynik był reprezentowany w tym formacie, zamiast klasy" Person "i dwóch relacji' Person.beards' i 'Person.mustashes'? Zasadniczo moje pytanie brzmi: dlaczego użyć 'sqlalchemy' do zrobienia czegoś tak' SQL'? Jeśli masz zdefiniowane relacje, możesz po prostu wydać 'session.query (Person) .options (linkedload ('beards')). Options (linkedload ('mustashes')). All()', a generowane zapytanie będzie bardzo podobnie, ale wynik byłby nadal instancją "Osoby", a nie "krotki". – van

Odpowiedz

2

Od @Francis P „s suggestion wymyśliłem tego fragmentu:

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

Jednak to działa, ale nie można nazwać jako odpowiedź ponieważ wygląda na włamywacza. Jest to kolejny powód, dla którego powinno być RIGHT OUTER JOIN w sqlalchemy.

-1

Dlaczego nie skorzystać z tej prostej kwerendy:

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

Problem tutaj nie jest pisaniem zapytania SQL o tym. Chodzi o to, jak zrobić SQLAlchemy jego reprezentację. Nawet odpowiedź, którą podałeś, jest czymś trudnym do napisania w SQLAlchemy. Byłoby świetnie, gdybyś mógł napisać to w SQLAlchemy. –

+1

jest o jakąkolwiek pomoc? http://stackoverflow.com/questions/7971798/sqlalchemy-union-with-different-number-of-columns –

+0

tak, to było pomocne. Dzięki :) –

1

Oto co mam, styl 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) 

który wydaje się działać na swój własny, ale wydaje się być niemożliwe, aby przyłączyć się do innej wybranej wypowiedzi

+0

Kiedy należy używać tego stylu ('select') zamiast" normalnego "(' session.query')? –

+0

@MatthewMoisen: o ile wiem, nie można umieścić ".query" wewnątrz klauzuli from. – Eric

Powiązane problemy