Skip to main content
 首页 » 编程设计

python之SQLAlchemy 多对多 AND 过滤器

2025年05月04日9luoye11

我有两个模型,通过多对多关系连接

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"] 
??? 

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

请您参考如下方法:

我看到了两种可能性:要么组合两个分别检查每个元素的 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 中的子查询必须返回标量结果。