我有物品和标签的m2m关系。我希望能够创建一个动态的AND查询,该查询将获得包含每个列出的标记的每个项目。
这是一个工作示例,但我希望它是动态的(随机数量的标签)。
return Item.query.filter(Item.item_tag.any(name = 'test'))\
.filter(Item.item_tag.any(name = 'tag'))\
.filter(Item.item_tag.any(name = 'tag1'))\
.filter(Item.item_tag.any(name = 'tag2'))\
.all()
这是或_:
的工作示例tags = or_( *[Tag.name==x for x in tags] )
return Item.query.join(Tag.items).filter(tags).all()
我正在为AND寻找类似的东西。
编辑:为工作AND解决方案生成的sql是:
SELECT item.id AS item_id, item.title AS item_title, item.url AS item_url, item.body AS item_body, item.itempic AS item_itempic, item.time_published AS item_time_published, item.private AS item_private, item.user_id AS item_user_id FROM item WHERE (EXISTS (SELECT 1 FROM item_tag, tag WHERE item.id = item_tag.item_id AND tag.id = item_tag.tag_id AND tag.name = ?)) AND (EXISTS (SELECT 1 FROM item_tag, tag WHERE item.id = item_tag.item_id AND tag.id = item_tag.tag_id AND tag.name = ?))
编辑2:
我需要的例子:Item1有标签:tag1,tag2,tag3。 Item2有标签:tag1,tag2,tag3,tag4。
搜索标签时:tag1,tag2,tag3。 item1和item2都返回。搜索标签时:tag1,tag2,tag3,tag4。只返回item2。
答案 0 :(得分:2)
也许我错过了明显的,但是:
tags = and_( *[Tag.name==x for x in tags] )
return Item.query.join(Tag.items).filter(tags).all()
参考:http://docs.sqlalchemy.org/en/rel_0_8/core/expression_api.html#sqlalchemy.sql.expression.and_
答案 1 :(得分:-2)
我不确定你是否非常清楚地表达了你的问题。
为什么要过滤然后迭代任何标签?为什么不只有Item.query.all()(如果你需要一个随机集,那么使用随机模块和.choice()来选择一些返回项)?
也许我误解了一些事情。从来没有需要这种查询。