2011-08-29 158 views
3

在sqlalchemy中,是否可以过滤由关系子查询返回的结果?考虑以下(请忽略任何语法/ API错误)sqlalchemy:在子查询上使用过滤器的子查询

关系:

User.address = relationship(Address, 
          secondary = UserAddress, 
          primaryjoin = (User.userid == UserAddress.userid), 
          secondaryjoin = (UserAddress.addressid == Address.addressid)) 

查询:

session.query(User).options(subqueryload(User.addresses)) 

这会给我的匹配连接条件的所有地址。但是,如果我想进一步过滤地址,该怎么办?例如,如果用户以访客身份登录,他/她应该只能看到另一个用户的公司地址,而不能看到他/她的家庭地址。所以像(假设):

if user_group == 'guest': 
    option = subqueryload(User.addresses).filter(Address.type != 'home') 
else: 
    option = subqueryload(User.addresses) 
q = session.query(User).options(options) 

这不能被表示为primaryjoin或secondaryjoin条件。在这种情况下我该怎么办?

感谢,

回答

0

你想要的地址,对不对?只是从另一端做一个简单的查询(user_id是一个参数):

qry = session.query(Address).join(User).filter(User.id == user_id) 
if user_group == 'guest': 
    qry = qry.filter(Address.type != 'home') 
addresses = qry.all() 
+1

我的例子是一个更大的问题的简化版本。您的解决方案在这种情况下工作,但我正在寻找一个通用的解决方案,使我能够将其他条件添加到连接条件。我会在下面提出另一个问题: – EnToutCas

+0

假设我有一个多租户系统,租户共享同一个表,并通过额外的键“systemid”进行区分。关系中的连接条件将具有Address.systemid == User.systemid,但是,在查询具有给定系统的地址的用户时,如果我们将关系加载到子查询中,则需要将systemid = $ current_systemid添加到连接条件或者我们最终得到一个可以进行全表扫描的子查询。所以需要''subquery.filter(Address.systemid == current_systemid)''。这只是为什么要在子查询上进行筛选的一个例子。 – EnToutCas

+0

很好的答案,范... thx! – Russ