Python 对列表中的每个项目进行筛选,以检查其是否位于ID';s

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

我只想得到每个游戏类别的结果,该类别在id列表中,执行以下操作不起作用。Game.categories是一个混合属性,它为我提供了游戏的类别

这是我正在做的查询,希望得到一个在我指定的ID列表中至少有一个类别的所有游戏的列表

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一无所知