You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQLAlchemy中获取指定属性无重复的ORM对象列表

在SQLAlchemy中获取指定字段无重复的记录数组

要实现按email字段去重,保留每个邮箱对应的一条用户记录(如示例中保留Bob而非John),可以用以下几种方法:

方法1:子查询+分组取主键(通用所有数据库)

假设User表有自增主键id,通过子查询获取每个邮箱对应的最小id,再关联查询完整用户记录:

from sqlalchemy import func, select

# 子查询:分组获取每个email对应的最小用户ID
subquery = select(func.min(User.id)).group_by(User.email).subquery()

# 主查询:筛选出对应ID的用户
unique_users = session.query(User).filter(User.id.in_(subquery)).all()

这种方式兼容性强,适用于所有数据库,且能明确控制保留哪条记录(通过取最小/最大主键)。

方法2:PostgreSQL专属的distinct_on

如果使用PostgreSQL,可以直接用distinct_on指定去重字段,结合排序确保返回预期记录:

# 按email去重,保留每个邮箱分组中id最小的用户
unique_users = session.query(User).distinct(User.email).order_by(User.email, User.id).all()

distinct_on会保留每个分组中排序后的第一条记录,必须配合order_by使用,否则结果不确定。

方法3:窗口函数(适用于复杂排序场景)

如果需要更灵活的排序规则(如按创建时间排序),可以用窗口函数给每个邮箱分组的记录编号,再筛选编号为1的记录:

from sqlalchemy import over, row_number

# 子查询:给每个email分组的记录按id排序并编号
ranked_subquery = session.query(
    User,
    row_number().over(partition_by=User.email, order_by=User.id).label('row_num')
).subquery()

# 筛选每个分组的第一条记录
unique_users = session.query(User).join(
    ranked_subquery, User.id == ranked_subquery.c.id
).filter(ranked_subquery.c.row_num == 1).all()

注意事项

  • 无论哪种方法,都必须指定排序规则(如id、创建时间),否则数据库返回的去重后记录是随机的,无法保证符合预期。
  • 如果User表没有主键,可以用其他唯一标识字段替代id进行筛选。

内容的提问来源于stack exchange,提问作者a55le

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 10:20:02