2013-10-01 4 views
1

subqueryload/subqueryload_all 꽤 많이 사용하고 있으며 subqueryload 동안 사용되는 쿼리를 매우 명시 적으로 정의해야하는 경우가 있습니다. 예를 들어 게시물과 의견이있는 경우가 있습니다. 내 검색어는 다음과 같습니다.subqueryload_all에서 사용되는 쿼리를 명시 적으로 정의하는 방법은 무엇입니까?

posts_q = db.query(Post).options(subqueryload(Post.comments)) 

자세히 알 수 있듯이 각 게시물의 댓글을로드하고 있습니다. 문제는 내가 모든 게시물의 주석을 원하지 않는다는 것, 삭제 된 필드를 고려해야하며, 생성 시간이 내림차순으로 정렬되어야한다는 것입니다. 이 작업이 수행 된 것을 확인한 유일한 방법은 게시물과 주석 사이에 relationship() 선언에 옵션을 추가하는 것입니다. 나는 이것을하지 않기를 바랄 것이다. b/c는 그 관계가 적용되지 않을 수도있는 앱의 다른 장소를 가지고 있기 때문에, 그 관계가 그 후 어디서나 재사용 될 수 없다는 것을 의미한다.

내가하고 싶은 것은 명시 적으로 subqueryload/subqueryload_all이 게시물의 설명을로드하는 데 사용하는 쿼리를 정의하는 것입니다. DisjointedEagerLoading here에 대해 읽었을 때 기본 쿼리를 사용하는 특수 함수와 지정된 관계를로드하는 쿼리를 간단히 정의 할 수있는 것처럼 보입니다. 이 상황에 적합한 방법일까요? 누구든지 전에이 끔찍한 사건에 빠졌습니까?

답변

1

나는 또한이 문제가있어서 설계 상 문제라는 것을 깨닫는 데 약간 시간이 걸렸다. Post.comments라고 말하면 "이들은 모두 해당 게시물의 주석입니다"라는 관계를 참조하십시오. 그러나 이제 필터를 필터링하려고합니다. subqueryload 어딘가에 조건을 지정했다면 본질적으로 값의 하위 집합 만 Post.comments에로드합니다. 따라서 가치가 누락 될 것입니다. 본질적으로 모델에서 데이터를 잘못 표현했습니다.

이 값은 어딘가에 분명히 필요하기 때문에 여기에 접근하는 방법은입니다. 내가가는 방법은 하위 쿼리를 직접 작성한 다음 특수 조건을 지정하는 것입니다. 즉, 두 개의 객체를 다시 가져올 수 있습니다. 게시물 목록과 주석 목록. 그것은 꽤 해결책은 아니지만 최소한 잘못된 방식으로 데이터를 표시하지는 않습니다. 어떤 이유로 든 Post.comments에 액세스하는 경우 모든 게시물이 있다고 가정 할 수 있습니다.

개선의 여지가 있습니다. 클래스에이 변수를 연결하여 두 변수를 전달하지 않을 수 있습니다. 쉬운 방법은 두 번째 관계를 정의하는 것입니다. 여분의 매개 변수를 지정하는 published_comments. 그러면 아무도 그에게 글을 쓰지 못하게 할 수 있습니다. attribute events. 이러한 이벤트에서 조작을 금지하는 대신 조작이 허용되는 방법을 처리 할 수 ​​있습니다. 유일한 문제는 업데이트가 발생할 때입니다. Post.comments에 의견을 추가하면 published_comments은 서로를 인식하지 못하기 때문에 자동으로 업데이트되지 않습니다. 다시 말하지만, 이것이 필수 기능이라면 이벤트를 취할 것입니다 (하지만 위의 추악한 솔루션으로는 그 중 하나도 없을 것입니다).

마지막 하이브리드 솔루션으로 첫 번째 접근 방식을 사용하고 그 값을 개체에 할당하면됩니다. Post.deleted_comments = deleted_comments.

여기서 유의해야 할 점은 ORM이 만드는 쿼리를 조작하는 것이 일반적으로 영리한 생각이 아니라는 것이므로 나중에 문제가 발생할 수 있습니다. 나는이 접근법을 취하여 질의를 조작했다. (이것은 쉽게 가능하다.) 그러나 그것은 몇몇 점들 (일반적으로 기능적 임)에 문제를 일으켜서 그 접근법을 떨어 뜨렸다.

posts_q = db.query(Post).options(subqueryload(Post.active_comments)) 

당신은 여전히 ​​사용할 수 있습니다 : 그럼 당신은 그 관계에 의해 subqueryload 할 수 있어야한다

class Post(...): 
    active_comments = relationship(Comment, 
     primary_join=and_(Comment.post_id==Post.post_id, Comment.deleted=False), 
     order_by=Comment.created.desc()) 

:

+0

상황에 대한 흥미로운 설명. 나는 결국'contains_eager' 라우트를 선택했습니다. 여러 관계에 대한 추가 제안을 해 주셔서 감사합니다. 이전에는 생각했지만 그 사실을 확신 할 수 없었습니다. 당신은 그런 식으로하는 주요 함정을 지적했습니다. – JayD3e

2

대답은 당신이 Post들과 Comment의 사이에 여러 관계를 정의 할 수 있다는 것입니다 기존 .comments 관계가 있습니다.