2012-07-09 40 views
6

Tôi có hai bảng beardmoustache định nghĩa dưới đây:RIGHT OUTER JOIN trong SQLAlchemy

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

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

tôi đã tạo ra một truy vấn SQL trong PostgreSQL mà sẽ kết hợp hai bảng này và tạo ra kết quả sau:

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

Truy vấn:

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" 

Tuy nhiên tôi không thể tạo đại diện SQLAlchemy của nó. Tôi đã thử một số cách để triển khai from_statement đến outerjoin nhưng không có cách nào thực sự hiệu quả. Bất cứ ai có thể giúp tôi với nó?

+0

gì mà "ON" khoản nghĩa là? –

+0

nó không thực hiện kiểm tra để thực hiện 'join' –

+0

Tại sao bạn muốn kết quả được biểu diễn trong định dạng này chứ không phải là một lớp' Person' và hai mối quan hệ 'Person.beards' và' Person.mustashes'? Về cơ bản câu hỏi của tôi là: tại sao sử dụng 'sqlalchemy' để làm một cái gì đó để' SQL'? Nếu bạn có các mối quan hệ được định nghĩa, bạn có thể chỉ phát hành các phiên 'session.query (Person) .options (linkedload ('beards')). tương tự, nhưng kết quả sẽ vẫn là một cá thể của 'Person' và không phải là một' tuple'. – van

Trả lời

2

Từ @Francis P 's suggestion tôi đã đưa ra đoạn mã này:

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

Tuy nhiên làm việc này, nhưng bạn không thể gọi nó như là một câu trả lời bởi vì nó xuất hiện như một hack. Đây là một trong nhiều lý do tại sao nên có RIGHT OUTER JOIN trong sqlalchemy.

-1

Tại sao không sử dụng truy vấn đơn giản này:

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

Vấn đề ở đây không phải là viết truy vấn SQL của nó. Nó nằm trong cách làm cho SQLAlchemy đại diện cho nó. Ngay cả câu trả lời bạn đã đưa ra cũng là một điều khó khăn để viết trong SQLAlchemy. Nó sẽ là tuyệt vời nếu bạn có thể viết nó trong SQLAlchemy. –

+1

là sự giúp đỡ nào? http://stackoverflow.com/questions/7971798/sqlalchemy-union-with-different-number-of-columns –

+0

có, nó rất hữu ích. Cảm ơn :) –

1

Đây là những gì tôi đã có, ORM phong cách:

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) 

Mà dường như để làm việc trên riêng của nó, nhưng có vẻ là không thể tham gia với một biểu hiện chọn

+0

Khi nào kiểu này ('select') được sử dụng thay vì cách" bình thường "(' session.query')? –

+0

@MatthewMoisen: như tôi biết, bạn không thể đặt một '.query' bên trong một mệnh đề từ. – Eric

Các vấn đề liên quan