在使用内部联接和外部联接创建查询时遇到问题

时间:2011-10-31 01:50:04

标签: python sqlalchemy pyramid

我有以下模型(简化):

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)

class Thing(Base):
    __tablename__ = 'thing'
    id = Column(Integer, primary_key=True)

class Relationship(Base):
    __tablename__ = 'relationship'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('thing.id'))
    parent = relationship('Thing', backref='parentrelationships', primaryjoin = "Relationship.parent_id == Thing.id")
    child_id = Column(Integer, ForeignKey('thing.id'))
    child = relationship('Thing', backref='childrelationships', primaryjoin = "Relationship.child_id == Thing.id")

class Vote(Base)
    __tablename__ = 'vote'
    id = Column(Integer, primary_key=True)
    rel_id = Column(Integer, ForeignKey('relationship.id'))
    rel = relationship('Relationship', backref='votes')
    voter_id = Column(Integer, ForeignKey('user.id'))
    voter = relationship('User', backref='votes')

我想查询某个父母的所有关系,我还想查询某个用户对这些关系所做的投票。我尝试了什么:

def get_relationships(thisthing, thisuser):
    return DBSession.query(Relationship, Vote).\
        filter(Relationship.parent_id == thisthing.id).\
        outerjoin(Vote, Relationship.id == Vote.rel_id).\
        filter(Vote.voter_id == thisuser.id).\
        filter(Vote.rel_id == Relationship.id).\
        all()

以及:

def get_relationships(thisthing, thisuser):
    session = DBSession()
    rels = session.query(Relationship).\
        filter(Relationship.parent_id == thisthing.id).\ 
        subquery()
    return session.query(rels, Vote).\
        outerjoin(Vote, rels.c.id == Vote.rel_id).\
        filter(Vote.voter_id == thisuser.id).\
        all()

当我执行其中任何一个查询时,我得到空值。我做错了什么?

1 个答案:

答案 0 :(得分:2)

只需启用SQL日志记录(echo=True),您将看到第一个选项的结果SQL查询类似于:

SELECT relationship.id AS relationship_id, relationship.parent_id AS relationship_parent_id, relationship.child_id AS relationship_child_id, vote.id AS vote_id, vote.rel_id AS vote_rel_id, vote.voter_id AS vote_voter_id 
FROM relationship LEFT OUTER JOIN vote ON relationship.id = vote.rel_id 
WHERE relationship.parent_id = ? AND vote.voter_id = ? AND vote.rel_id = relationship.id

如果你检查它,你会注意到vote.rel_id = relationship.id子句是JOIN子句和WHERE子句的一部分,这使得查询过滤掉{{1}所请求的用户没有任何投票的行。

解决方案:

  1. 从查询中删除多余的Relationship部分。
  2. Edit-1 :同时从[{1}}移出(移除)用户filter(Vote.rel_id == Relationship.id).的过滤器并移至filter(Vote.voter_id == thisuser.id)子句:{{1} }。