2017-11-11 2 views
0

안녕하세요, 내가 joinload를 사용하여 내 쿼리로 필터를하고 싶습니다. 그러나 나는 그것을 작동하게하는 것처럼 보일 수 없다. 아래 샘플은 내 검색어입니다SQLAlchemy Joinedload 필터 열

result = (
     session.query(Work). 
     options(
      joinedload(Work.company_users). 
      joinedload(CompanyUser.user) 
     ). 
     filter(Work.id == 1). 
     filter(User.first_name == 'The name'). <<--- I can't get this to work. 
     all() 
    ) 

실행하면 예상보다 많은 행이 반환됩니다. 실제 결과는 8rows 만 리턴해야합니다. 그러나이 쿼리를 실행하면 234 행을 반환하는데 이는 예상 한 것보다 많습니다.

답변

1

알았습니다. 내가 한 일은 joined_eager에 대한 joinedload를 대체하고 join을 추가하는 것이 었습니다. 아래는 작동하지 않는 이유는 joinedload (다른 모든 관계 로딩 기술)가 완전히 투명하게하기위한 것입니다 있다는 것입니다 개정 코드

result = (
    session.query(Work). 
    join(Work.company_users). 
    join(CompanyUser.user). 
    options(
     contains_eager(Work.company_users). 
     contains_eager(CompanyUser.user) 
    ). 
    filter(Work.id == 1). 
    filter(User.first_name == 'The name'). <<--- I can't get this to work. 
    all() 
) 
1

입니다. 즉, 쿼리에 joinedload을 가져도 관계가 채워지는 것 이외의 다른 방법으로 영향을 미치지 않아야합니다. 당신은 시작 "The Zen of Joined Eager Loading", 읽어야에 가입 열망 로딩이 Query.join()의 사용에 많은 유사성을 갖고있는 것 같아요 때문에

, 그것은 자주 사용해야하는시기와 방법에 혼란을 생산하고 있습니다. Query.join()은 쿼리 결과를 변경하는 데 사용되지만 joinedload()은 쿼리 결과를 변경하지 않고 많은 시간을 거쳐 관련 개체 만 허용하도록 렌더링 된 조인의 효과를 숨기는 것이 중요합니다. 참석하십시오.

트릭 중 하나는 사용할 수 없게 된 조인 된 테이블에 별칭을 사용하는 것입니다. 그런 다음 쿼리는 Work와 User 사이의 암시 적 크로스 조인을 수행하고 결과적으로 추가 행을 수행합니다. 그래서 조인 된 테이블에 대해 필터링하기 위해, Query.join()을 사용 이미 포함

session.query(Work).\ 
    join(Work.company_users).\ 
    join(CompanyUser.user).\ 
    filter(Work.id == 1).\ 
    filter(User.first_name == 'The name').\ 
    all() 

을하고 당신은 또한 장소에 eagerloads을 필요로하는 경우, 당신은 쿼리를 지시 할 수있는 contains_eager() 조인 :

session.query(Work).\ 
    join(Work.company_users).\ 
    join(CompanyUser.user).\ 
    options(contains_eager(Work.company_users). 
      contains_eager(CompanyUser.user)).\ 
    filter(Work.id == 1).\ 
    filter(User.first_name == 'The name').\ 
    all() 

contains_eager()으로 연결된 통화에 유의하십시오.