2013-01-16 2 views
5

많은 관계 객체에 대한 모든 많은으로 선택 SQLAlchemy의?많은 관계로이 많은 감안할 목록

원하는 쿼리 결과 구조하십시오 신사 템플릿

[ <Post 1, "Blah",  [<Tag "Goober">, <Tag "Mexico">]>, 
    <Post 2, "Daft Punk", [<Tag "French">]>, 
    <Post 3, "Slurpee", [<Tag "Diabetes">, <Tag "Tasty">, <Tag "Sugary">]>, 
    <Post 4, "Lasers", []> ] 

예 원하는 결과 사용 :

{% for post in posts %} 
    {{ post.text }} 
    <hr> 
    {% for tag in post.tags %} 
     {{ tag.name }}, 
    {% endfor %} 
{% endfor %} 

편집 : 쿼리를 확장하려고 할 때

는 태그가 중지 포함된다.

posts = db.session.query(Post, User.name.label('author')).join(User)\ 
      .options(db.joinedload(Post.tags))\ 
      .order_by(Post.created.desc()).limit(5) 

을하지만 포스트 열에 대한 선택적 수 있도록하려면 내가 선택 :

그래서이 쿼리가 잘 작동 :

Post.query.join(User)\ 
    .options(db.joinedload(Post.tags))\ 
    .order_by(Post.create_date.desc()).limit(5)\ 
    .values(User.name.label('author'), 
      Post.create_date, 
      Post.text,) 

편집 2 아래에 실패한 쿼리를 참조

# I only need the post text, nothing else 
posts = db.session.query(Post.text, User.name.label('author')).join(User)\ 
      .options(db.joinedload(Post.tags))\ 
      .order_by(Post.created.desc()).limit(5) 

빠르게 부서지기 시작합니다.

ArgumentError: Query has only expression-based entities - can't find property named 'tags'. 

그래서 나는 태그를 다시 추가하려고하면 계속 실패

# Yes, I know this is wrong 
posts = db.session.query(Post.text, Post.tags, User.name.label('author'))\ 
      .join(User)\    
      .options(db.joinedload(Post.tags))\ 
      .order_by(Post.created.desc()).limit(5) 

합니다.

그래서 부모 개체 (Post)의 특정 열만 원한다면 "내가 여전히 태그를 원합니다"라는 표현에서 어디에서 말할까요?

지금은별로 중요하지 않지만, 알고 있으면 유용 할 것이라고 생각했습니다. 또는 그것이 불가능하다는 것을 알고 있습니다.

답변

6

열심히로드을 관계에 사용한다고 가정합니다.

class Post(db.Model): 
    # ... 
    tags = db.relationship('Tag', secondary=tagmap, backref='posts', 
          lazy='joined') # Or lazy='subquery' 

아니면 쿼리 당을 설정할 수 있습니다 :

q = Post.query.options(db.joinedload(Post.tags)).all() 
# Or db.subqueryload(Post.tags) 

Eager Loading ORM 튜토리얼의 일부 Relationship Loading Techniques에 대한 참조 당신도 'joined' 또는 'subquery'에 관계 lazy 키워드 인수를 설정하여 그것을 달성 할 수 자세한 내용은.

+0

아름답습니다, 선생님 고마워요! – Elliott

+0

어떻게'joinedval' 문을 더 복잡한 쿼리에 포함 시키시겠습니까? 예를 들어'.values ​​()'를 사용하는 경우? (예제 쿼리로 내 질문을 업데이트했습니다.) – Elliott

+0

우선,'values ​​()'인수에서'Post.tags'를 사용하지 않고 있습니다. 관계와 관련이 없다고 생각합니다. , 적어도 다른 코드를 사용하면 빠른 테스트를 수행하지 못합니다. 여러 테이블에서 값을 쿼리하려면이 경우 db.session.query (...)를 사용하지 않는 것이 좋을까요? –

0

SQLAlchemy는 액세스 할 때 post.tags 속성을 자동로드하므로 원하는 모든 게시물 만로드하면됩니다.

db.Column('tag_id', db.Integer, db.ForeignKey('quotes.id'),)

quotes.id 오타인가요?

+0

예. 오타였습니다. 외장 키를 수정 했으므로 이제는 이해합니다. – Elliott