Как мне вернуть разные значения с помощью graphene_sqlalchemy?
Я пытаюсь вернуть разные значения из запроса GraphQL.
from graphene_sqlalchemy import SQLAlchemyConnectionField
import graphene
from database.model import MyModel
class Query(graphene.ObjectType):
"""Query objects for GraphQL API."""
node = graphene.relay.Node.Field()
distinct_values = graphene.List(graphene.String, search=graphene.String())
def resolve_distinct_values(self, info, search=None, **kwargs):
return MyModel.field.distinct()
schema = graphene.Schema(query=Query)
Ответ, который я получаю на свой запрос ownValues:
{
"message": "User Error: expected iterable, but did not find one for field Query.distinctValues."
}
Я не замечаю здесь чего-то простого. Для чего предназначен отдельный ()?
1 ответ
SQLAlchemy's distinct
метод используется для добавления DISTINCT
пункт к вашему запросу. DISTINCT
удалит все повторяющиеся строки.
Если вы используете PostgreSQL, вы также можете использовать необязательный параметр, distinct(*expr)
, чтобы сделать DISTINCT ON (<expressions>)
пункт. Это сохранит только "первую строку" каждого набора строк, где заданные выражения (*expr
) равным. Вам нужно будет использовать SQLAlchemyorder_by
чтобы убедиться, что нужная строка появляется первой.
Метод SQLAlchemy Query.distinct(*expr).
Предложение DISTINCT в PostgreSQL.
В этом примере показана игра, в которой игроки могут путешествовать по разным островам, посещение записывается каждый раз, когда игрок прибывает на остров. Мы можем использовать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"
}
}
}
]
}
}
}