如何使用PythonList(必须具有全部或至少具有一个元素)在具有SQLAlchemy的多对多结构上执行查询?

如何使用PythonList(必须具有全部或至少具有一个元素)在具有SQLAlchemy的多对多结构上执行查询?,python,mysql,sqlalchemy,many-to-many,Python,Mysql,Sqlalchemy,Many To Many,我将创建一个不特定的结构,这样问题就更容易理解了。考虑到存储书籍信息的数据库结构: 从flask_sqlalchemy导入sqlalchemy 从美国进口棉花糖 db=SQLAlchemy 基类来创建一些好的实践字段 类Basedb.Model: __抽象=真 id=db.Columndb.Integer,主键=True 创建日期=db.Columndb.DateTime,默认值=db.func.current\u时间戳 修改日期=db.Columndb.DateTime,默认值=db.func

我将创建一个不特定的结构,这样问题就更容易理解了。考虑到存储书籍信息的数据库结构:

从flask_sqlalchemy导入sqlalchemy 从美国进口棉花糖 db=SQLAlchemy 基类来创建一些好的实践字段 类Basedb.Model: __抽象=真 id=db.Columndb.Integer,主键=True 创建日期=db.Columndb.DateTime,默认值=db.func.current\u时间戳 修改日期=db.Columndb.DateTime,默认值=db.func.current\u时间戳, onupdate=db.func.current\u时间戳 类别书库: name=db.Columndb.String255,null=False pages=db.Columndb.Integer,null=True tags=db.关系'BooksTags',back_populates=book 类别BooksTagsdb.Model: __tablename\uuuu='book\u标签' tag\u id=db.Columndb.Integer,db.ForeignKey'book.id',primary\u key=True book\u id=db.Columndb.Integer,db.ForeignKey'tag.id',primary\u key=True book=db.关系'book',back_填充='tags' tag=db.relationship'tag',back_填充='books' 类别标记库: name=db.Columndb.String255,null=False books=db.relationship'BooksTags',back\u populates=tag 使用这段代码,我有一个多对多的结构,对我来说效果很好,但是当我尝试创建基于标记的查询时,我被卡住了,例如:

如何查询此结构以获取所有标签都存在于标签列表中且页面数最少的书籍? 如果需要在列表上至少显示一个标记,该怎么办? 我一直在尝试使用一些聚合函数,如array_agg和group_concat,但我总是返回不同的错误消息,我不知道如何做

在纯SQL上,我会查询如下内容:

选择 组_concattag.name作为标记, book.name作为book\u name 从…起 书 book.id上的内部联接book\u标记=book\u标记.book\u id tag.id上的内部联接标记=book\u tag.tag\u id 分组 书号 但是IDK知道如何过滤这个查询

好的,在阅读并询问了一些朋友的帮助后,我成功地用SQL实现了这一点:

如果至少有一个标签:

选择 组_concattag.name作为标记, book.name作为book\u name 从…起 书 book.id上的内部联接book\u标记=book\u标记.book\u id tag.id上的内部联接标记=中的book_tag.tag_id和tag.name 分组 书号 如果是,则必须具有所有标签:

选择 组_concattag.name作为标记, book.name作为book\u name 从…起 书 book.id上的内部联接book\u标记=book\u标记.book\u id tag.id上的内部联接标记=中的book_tag.tag_id和tag.name 分组 书号 哪里 COUNTtag.name>
但我仍然不知道如何使用SQLAlchemy进行筛选。

您应该能够按如下方式筛选书籍:

filtered = Book.query().filter(Book.tags.tag.name == 'tag_name')
根据您的标准,您可以制作一个循环,使其符合您的需要

您可以使用在原始过滤器的顶部设置其他过滤器

filtered.filter()

编辑之后,解决问题就更容易了,因此要选择至少有一个数组标记的所有书籍:

标记_id=[1,2,3] books\u query=Book.query.joinBooksTags,Tag books\u query=books\u query.filterBooksTags.tag\u id.in\u tags\u id books\u query=books\u query.group\u byBook 这将返回类似这样的结果

选择 book.id作为book\u id, book.name作为book\u name, book.pages作为book\u页面 从…起 书 book.id上的内部联接book\u标记=book\u标记.book\u id tag.id上的内部联接标记=book\u tag.tag\u id 哪里 中的book\u tag.tag\u id 1. 2. 3. 分组 图书编号, 书名, 书页 要进行选择,请选择具有该数组所有标记的所有书籍:

标记_id=[1,2,3] books\u query=Book.query.joinBooksTags,Tag books\u query=books\u query.filterBooksTags.tag\u id.in\u tags\u id books\u query=books\u query.group\u byBook books\u query=books\u query.havingfunc.countBook.id>=lentags\u id 这将返回类似这样的结果

选择 book.id作为book\u id, book.name作为book\u name, book.pages作为book\u页面 从…起 书 book.id上的内部联接book\u标记=book\u标记.book\u id tag.id上的内部联接标记=book\u tag.tag\u id 哪里 中的book\u tag.tag\u id 1. 2. 3. 分组 图书编号, 书名, 书页 有 countbook.id>=3
我已经尝试过了,但我收到了以下错误消息:AttributeError:与Book.tags关联的'InstrumentedAttribute'对象和'Comparator'对象都没有属性'tag_id'我的代码:filtered=filtered.filterBook.tags.tag_id.in.[戏剧性,动作]