SQLAlchemy:如何在连接查询中的过滤器之前应用 distinct

Posted

技术标签:

【中文标题】SQLAlchemy:如何在连接查询中的过滤器之前应用 distinct【英文标题】:SQLAlchemy : how to apply distinct before a filter in a join query 【发布时间】:2020-04-28 10:28:58 【问题描述】:

有没有办法在连接查询中过滤之前应用 distinct ?

我有 2 张桌子:

class User(db.Model):
  id = db.Column(db.Integer(), primary_key=True)

class Event(db.Model):
  id = db.Column(db.Integer(), primary_key=True)
  date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
  description = db.Column(db.String(80))
  user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
  user = db.relationship('User', backref=db.backref('events', lazy=True))

我想选择最近事件描述为空的所有用户。

我认为这会起作用:

User.query.join('events').order_by(Event.date).distinct(User.id).filter(Event.description==None)

但是,似乎在过滤器之后调用了 distinct。有没有办法在过滤之前强制应用 distinct ?

【问题讨论】:

【参考方案1】:

DISTINCT 用于返回不同的值。

在这种情况下,您需要一个子查询来使用 GROUP BY 创建一个表,其中您将 Eventuser_id 分组并计算最近的事件:

last_events = db.session.query(
                    Event.user_id, 
                    db.func.max(Event.date).label('last_event_date'),
                    Event.description)\
                        .group_by(Event.user_id)
                        .subquery()

然后您可以将此表加入User 并根据 last_event_description 进行过滤:

User.query.join(last_events,User.id==last_events.c.bac_id)
            .filter(last_events.c.description==None)

等等!

.c 来自于您在 SQLAlchemy 中访问子查询列的方式。

【讨论】:

以上是关于SQLAlchemy:如何在连接查询中的过滤器之前应用 distinct的主要内容,如果未能解决你的问题,请参考以下文章

如何在 sqlalchemy 查询过滤器中使用用户定义的 python 函数?

在 sqlalchemy 中的查询级别连接列

在 graphene-sqlalchemy 查询中按 id 过滤

您如何设置 sqlalchemy 关系ihp,以便子查询负载将根据属性过滤我们的结果

SQLAlchemy - 过滤子查询负载

嵌套的一对多关系 sqlalchemy 过滤