寻找多对多的关系

时间:2014-03-11 11:41:20

标签: python sqlalchemy flask-sqlalchemy

如何在sqlalchemy中搜索多对多关系中的列表。在下面的示例中,我想搜索包含一组标签的帖子。我可以搜索包含特定标签的帖子,但不能搜索标签列表:

class Post(Base):
    __tablename__ = 'posts'
    id    = Column(Integer, primary_key=True)
    text  = Column(Text)
    tags  = relationship('Tag', secondary=tagmap, backref='posts')
    def __init__(self, id, text, tags):
        self.id = id
        self.text = text
        self.tags = tags

class Tag(Base):
    __tablename__ = 'tags'
    id    = Column(Integer, primary_key=True)
    name  = Column(String)
    def __init__(self, id, name):
        self.id = id
        self.name = name

def postsTest():
    tag1 = Tag(1, "aa")
    tag2 = Tag(2, "bb")
    tag3 = Tag(3, "cc")
    sess.add(tag1)
    sess.add(tag2)
    sess.flush()

    post = Post(1, "blah:", [tag1, tag2, tag3])
    sess.add(post)
    sess.flush()

    # this works
    for p in sess.query(Post).filter(Post.tags.contains(tag1)).all():
        print str([tag.name for tag in p.tags])

    #this doesn't
    for p in sess.query(Post).filter(Post.tags.contains([tag2, tag3])).all():
        print str([tag.name for tag in p.tags])

postsTest()

1 个答案:

答案 0 :(得分:1)

下面应该做的诀窍:

q = sess.query(Post).filter(
        and_(
            Post.tags.contains(tag2),
            Post.tags.contains(tag3),
            )
        ).all()

您可以将and_替换为or_,如果您愿意,也可以根据需要添加。{/ p>

但是,我认为你不想搜索特定标签的帖子,我想你想找到具有特定tag name(s)的帖子。如果是这种情况,你应该这样做:

# get all Posts with has a least one tag from the list ["aa", "bb"]
q = sess.query(Post).filter(Post.tags.any(Tag.name.in_(["aa", "bb"])))

# get all Post with all of the tags in the list ["aa", "bb"]
q = sess.query(Post).filter(
        and_(
            Post.tags.any(Tag.name.in_(["aa"])),
            Post.tags.any(Tag.name.in_(["bb"])),
            )
        )