SQLAlchemy多对多AND过滤器

时间:2013-08-20 21:26:53

标签: python sql sqlalchemy

我有两个模型,由多对多关系加入

image_tag = Table('image_tag', Base.metadata,
    Column('image_id', Integer, ForeignKey('images.id')),
    Column('tag_id', Integer, ForeignKey('tags.id'))
)

class Image(Base):
    __tablename__='images'
    id = db.Column(db.Integer, primary_key=True)
    tags = relationship('Tag', secondary=image_tag, backref=backref('images', order_by=id.desc()), lazy="joined")

class Tag(Base):
    __tablename__ = 'tags'
    id = Column(Integer, primary_key=True)
    tag = Column(String(64), unique=True)

现在假设我想按标签过滤图片 - 简单:

_tag = "foo"
Image.query.filter(Image.tags.any(tag=_tag)).all()

但是,如果我想过滤多个标签并且只想匹配那些匹配所有标签的图片呢?

tags = ["foo", "bar"]
???

任何帮助都非常感激。谢谢!

1 个答案:

答案 0 :(得分:1)

我看到两个可能性:要么合并两个EXIST子句,分别检查每个元素,要么指定where子句,如下所示:

WHERE (SELECT COUNT(*) FROM ... WHERE tags.tag in ("foo", "bar")) = 2

这两个解决方案都有点难看但我在这里看到的问题更多的是SQL的方式而不是SQLAlchemy。

在这两种情况下,我建议您首先构建一个普通的SQL查询,测试它,并在SQLAlchemy中等效地构建它。

顺便说一句,我可以想象这两种解决方案在大型数据集上的效率非常低,但我在这里看不到解决方案。

最初,我会尝试像WHERE (SELECT tags.tag FROM ...) = ("foo", "bar")这样的东西,但似乎不是有效的SQL(至少MySQL向我提出错误),因为WHERE中的子查询必须返回标量结果。