SQLAlchemy 的distinct
方法用于DISTINCT
向您的查询添加子句。DISTINCT
将删除所有重复的行。
如果您使用的是 PostgreSQL,您还可以使用可选参数distinct(*expr)
, 来呈现DISTINCT ON (<expressions>)
子句。*expr
这将只保留给定表达式 ( ) 评估为相等的每组行的“第一行” 。您需要使用 SQLAlchemy 的order_by
方法来确保所需的行首先出现。
SQLAlchemy 的 Query.distinct(*expr) 方法。
PostgreSQL 的 DISTINCT 子句。
这个例子展示了一个游戏,其中玩家可以前往不同的岛屿,每次玩家到达一个岛屿时都会记录一次访问。我们可以使用该lastVisit
字段显示最近访问过每个岛屿的玩家。
# models.py
import enum
from sqlalchemy import Column, DateTime, Enum, ForeignKey, Integer, String, orm, sql
class Player(Base):
id = Column(Integer, primary_key=True)
username = Column(String(50), unique=True)
visits = orm.relationship("Visit", backref="visitor")
class Island(enum.Enum):
Amity = "amity"
IslaNublar = "islanublar"
Skull = "skull"
Treasure = "treasure"
class Visit(Base):
id = Column(Integer, primary_key=True)
island = Column(
Enum(Island, name="island", values_callable=lambda x: [e.value for e in x]),
nullable=False,
)
arrived_at = Column(DateTime(timezone=False), nullable=False, server_default=sql.func.now(), index=True)
player_id = Column(ForeignKey("players.id"), nullable=False)
# schema.py
from sqlalchemy import orm
from models import Player as PlayerModel, Visit as VisitModel
class Player(SQLAlchemyObjectType):
class Meta:
model = PlayerModel
interfaces = (relay.Node,)
class Visit(SQLAlchemyObjectType):
class Meta:
model = VisitModel
interfaces = (relay.Node,)
class Query(graphene.ObjectType):
node = relay.Node.Field()
last_visit = SQLAlchemyConnectionField(Visit.connection, sort=None)
def resolve_last_visit(self, info):
return (
VisitModel.query.options(orm.joinedload(VisitModel.visitor))
.distinct(VisitModel.island)
.order_by(VisitModel.island, VisitModel.arrived_at.desc())
.all()
)
schema = graphene.Schema(query=Query)
这个查询:
{
lastVisit {
edges {
node {
island
visitor {
username
}
}
}
}
}
会产生这样的结果:
{
"data": {
"lastVisit": {
"edges": [
{
"node": {
"island": "AMITY",
"visitor": {
"username": "playertwo"
}
}
},
{
"node": {
"island": "ISLA_NUBLAR",
"visitor": {
"username": "playerthree"
}
}
},
{
"node": {
"island": "SKULL",
"visitor": {
"username": "playerone"
}
}
},
{
"node": {
"island": "TREASURE",
"visitor": {
"username": "playerthree"
}
}
}
]
}
}
}