2014-10-16 2 views
4

저자 테이블과 게시 테이블이 있으며 각 작성자는 여러 개의 게시물을 가질 수 있습니다.sqlalchemy를 사용하여 관련 테이블에서 하나의 행만 선택하십시오.

이제 단일 sqlalchemy 쿼리를 사용하여 모든 활성 작성자와 가장 최근 게시 된 각 게시를 가져오고 싶습니다. 나는이 같은 결과를 함께 그룹에 하위 쿼리를 사용하여 저자 joinedload 게시물의 목록을 얻어서이에 갈 노력했습니다

:

subquery = DBSession.query(Author.id, func.max(Post.publish_date).label("publish_date")) \ 
    .join(Post.author) \ 
    .filter(Post.state == 'published') \ 
    .filter(Author.state == 'active') \ 
    .group_by(Author.id) \ 
    .subquery() 

query = DBSession.query(Post) \ 
    .options(joinedload(Post.author)) \ 
    .join(Post.author) \ 
    .join(subquery, and_(Author.id == subquery.c.id, 
         Post.publish_date == subquery.c.publish_date)) 

을하지만이 게시물에서이있는 경우 동일한 publish_date를 가진 작성자와 가장 최근 게시물 인 경우 해당 저자가 내 결과 목록에 두 번 나타나게됩니다. 그리고 두 번째 하위 쿼리를 사용하여 속임수를 제거 할 수는 있지만 (func.max (Post.id) 가져 오기),이 문제를 해결하는 것은 정말 잘못된 방법입니다. 이 문제를 해결할 더 좋은 방법이 있습니까?

(다시 말하지만, 나는 단일 쿼리를 찾고 있어요, 그래서 나는 다음 통해 반복 내 결과에 모든 저자에 대한 포스트 쿼리를하고, 저자 테이블에 쿼리 피하기 위해 노력하고있어.)

+0

ORDER BY 절을 추가하는 경우 [이 답변] (http://stackoverflow.com/a/2043290/405075)을하고 싶습니다. 그러나 번역 방법을 모르겠습니다. 그 SQL에서 sqlalchemy. – shroud

+0

db가 윈도우 함수에 over 절을 지원하면 [this answer] (http://stackoverflow.com/a/17457858/1587090)의 접근 방식을 사용할 수 있습니다. –

답변

6

I 다음과 같이 할 것입니다 : 당신이 볼 수 있듯이

LastPost = aliased(Post, name='last') 
last_id = (
    session.query(LastPost.id) 
    .filter(LastPost.author_id == Author.id) 
    .order_by(LastPost.publish_date.desc()) 
    .order_by(LastPost.id.desc()) 
    .limit(1) 
    .correlate(Author) 
    .as_scalar() 
) 

query = (
    DBSession.query(Author, Post) 
    .outerjoin(Post, Post.id == last_id) 
) 

for author, last_post in query: 
    print(author, last_post) 

는, 결과는 쌍 (Author, LastPost)tuple입니다.
적어도 하나의 저자가 오직 Post 인 경우에만 outerjoinjoin으로 변경하십시오.
또한 혼란을 피하기 위해 Author.post 관계를 미리로드하지 않습니다.

관련 문제