Python 对列表中的每个项目进行筛选,以检查其是否位于ID';s
我只想得到每个游戏类别的结果,该类别在id列表中,执行以下操作不起作用。Game.categories是一个混合属性,它为我提供了游戏的类别 这是我正在做的查询,希望得到一个在我指定的ID列表中至少有一个类别的所有游戏的列表Python 对列表中的每个项目进行筛选,以检查其是否位于ID';s,python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,我只想得到每个游戏类别的结果,该类别在id列表中,执行以下操作不起作用。Game.categories是一个混合属性,它为我提供了游戏的类别 这是我正在做的查询,希望得到一个在我指定的ID列表中至少有一个类别的所有游戏的列表 games = Game.query \ .filter([category.id for category in Game.categories].in_([1, 2, 3])) \ .paginate(page, current_app.config['POST
games = Game.query \
.filter([category.id for category in Game.categories].in_([1, 2, 3])) \
.paginate(page, current_app.config['POSTS_PER_PAGE'], False)
我的模特就是这个。请注意,每个游戏的类别取决于用户定义的类别数量
class CategoryUpvote(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
game_id = db.Column(db.Integer, db.ForeignKey('game.id'))
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
class Game(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(255), index=True, unique=True)
category_upvotes = db.relationship('CategoryUpvote', backref='category', lazy='dynamic', cascade="save-update, merge, delete")
def add_upvote(self, category, user):
if not self.is_upvoted(category, user):
upvote = CategoryUpvote(category_id=category.id, game_id=self.id, user_id=user.id)
db.session.add(upvote)
else:
upvote = self.category_upvotes.filter(CategoryUpvote.category_id == category.id, CategoryUpvote.user_id == user.id, CategoryUpvote.game_id == self.id).first()
db.session.delete(upvote)
def is_upvoted(self, category, user):
return self.category_upvotes.filter(CategoryUpvote.category_id == category.id, CategoryUpvote.user_id == user.id, CategoryUpvote.game_id == self.id).count() > 0
@hybrid_property
def categories(self):
return Category.query \
.filter(CategoryUpvote.game_id == self.id, CategoryUpvote.category_id == Category.id) \
.group_by(Category.id) \
.order_by(db.func.count(CategoryUpvote.game_id).desc()) \
.limit(5) \
.all()
我得到这个错误
'list' object has no attribute 'in_'
我怎样才能为游戏的每个类别运行过滤器?比如说
.filter(Game.categories[0].in_([1, 2, 3]), Game.categories[1].in_([1, 2, 3]), Game.categories[2].in_([1, 2, 3])) \
另外,若游戏中的每个类别都是外键,我可以这样做
Game.query.join(Category).filter(Category.id.in_([1, 2, 3]))
如何对hybrid_属性执行类似操作?面临的问题是,您试图使用生成器运行查询
category.id.in_([1,2,3]) for category in Game.categories
给你举个小例子。运行以下代码时,您将在列表中获得所需的0到5的输出
>>> print([a for a in range(5)])
[0, 1, 2, 3, 4]
现在,如果您确实拆下方形支架
>>> print(a for a in range(5))
<generator object <genexpr> at 0x102829f10>
面临的问题是,您正试图使用生成器运行查询
category.id.in_([1,2,3]) for category in Game.categories
给你举个小例子。运行以下代码时,您将在列表中获得所需的0到5的输出
>>> print([a for a in range(5)])
[0, 1, 2, 3, 4]
现在,如果您确实拆下方形支架
>>> print(a for a in range(5))
<generator object <genexpr> at 0x102829f10>
属性
Game.categories
,虽然表示为hybrid_属性
,但在SQL上下文中不起作用。当用于在类级别创建时,它仍然对数据库执行实际查询,返回类别
对象列表。你的大多数错误都是由这个事实造成的
此外,它本质上在游戏
和分类YupNote
之间执行联接(使用SQL-92之前的样式),从所有游戏中返回5个最受欢迎的类别。如果属性返回查询
,而不具体化为列表,则通常会使属性更可用:
class Game(db.Model):
@hybrid_property
def categories(self):
return Category.query \
.join(CategoryUpvote) \
.filter(CategoryUpvote.game_id == self.id) \
.group_by(Category.id) \
.order_by(db.func.count(CategoryUpvote.game_id).desc()) \
.limit(5)
然后,您可以使用
game.categories.all()
或者直接迭代它。例如,通过混合属性返回查询,您现在可以使用它生成相关子查询。然后,您可以将基于中id列表过滤类别的尝试转换为谓词“给定id和由id
标识的游戏类别id之间的差异为空”,或者换句话说,所有给定id都包含在一个游戏的前5个类别id中:
# A portable way to build a (derived) table of ids. Use VALUES
# instead, if supported.
ids = union(*[select([literal(i).label('id')]) for i in [1, 2, 3]])
Game.query.filter(~exists(
ids.select()
.except_(Game.categories
.correlate(Game)
.with_entities(Category.id)
.subquery()
.select())))
请注意
我只想得到每个游戏类别的结果,该类别在id列表中
及
这是我所做的查询,我希望得到我指定的ID列表中至少有一个类别的所有游戏的列表
它们不是同一件事,上面的示例是在考虑前者的情况下编写的,尽管严格的解释(列表中的每个类别)需要使用对称差异
为了得到后者,您可以使用谓词“给定id和由
id
标识的游戏类别id之间的交集不是空的”进行查询,因此您可以交换to并删除前面的not运算符~
,因为如果某个对象不是空的,一行或多行存在。属性Game.categories
,虽然表示为混合属性
,但在SQL上下文中不起作用。当用于在类级别创建时,它仍然对数据库执行实际查询,返回类别
对象列表。你的大多数错误都是由这个事实造成的
此外,它本质上在游戏
和分类YupNote
之间执行联接(使用SQL-92之前的样式),从所有游戏中返回5个最受欢迎的类别。如果属性返回查询
,而不具体化为列表,则通常会使属性更可用:
class Game(db.Model):
@hybrid_property
def categories(self):
return Category.query \
.join(CategoryUpvote) \
.filter(CategoryUpvote.game_id == self.id) \
.group_by(Category.id) \
.order_by(db.func.count(CategoryUpvote.game_id).desc()) \
.limit(5)
然后,您可以使用
game.categories.all()
或者直接迭代它。例如,通过混合属性返回查询,您现在可以使用它生成相关子查询。然后,您可以将基于中id列表过滤类别的尝试转换为谓词“给定id和由id
标识的游戏类别id之间的差异为空”,或者换句话说,所有给定id都包含在一个游戏的前5个类别id中:
# A portable way to build a (derived) table of ids. Use VALUES
# instead, if supported.
ids = union(*[select([literal(i).label('id')]) for i in [1, 2, 3]])
Game.query.filter(~exists(
ids.select()
.except_(Game.categories
.correlate(Game)
.with_entities(Category.id)
.subquery()
.select())))
请注意
我只想得到每个游戏类别的结果,该类别在id列表中
及
这是我所做的查询,我希望得到我指定的ID列表中至少有一个类别的所有游戏的列表
它们不是同一件事,上面的示例是在考虑前者的情况下编写的,尽管严格的解释(列表中的每个类别)需要使用对称差异
为了得到后者,您可以使用谓词“给定id和由
id
标识的游戏类别id之间的交集不是空的”进行查询,因此您可以交换to并删除前面的not运算符~
,因为如果某个对象不是空的,存在一行或多行。感谢您的回答,但问题仍然存在。我正在尝试为每个游戏的每个类别运行过滤器,并编辑了上面的代码,以详细说明我已经更新了代码。我对sqlalchemy一无所知,所以您可能需要检查语法。我写的for循环也是不推荐的。我无法理解您试图实现的目标,因此我编写了循环。我更喜欢使用JoinDatabase做这件事谢谢你的回答,但问题仍然存在。我正在尝试为每个游戏的每个类别运行过滤器,并编辑了上面的代码,以详细说明我已经更新了代码。我对sq一无所知