如何进行可以查找&Quot;最新&Quot;、最小&Quot;或&Quot;最大&Quot;的GraphQL查询
问题描述
我正在尝试结合使用GraphQL和python来检索时间范围内的最低和最高温度。
温度表有2列:时间戳和值。
我的mods.py是:
from django.db import models
class Temperature(models.Model):
timestamp = models.DateTimeField(auto_now=True)
value = models.FloatField()
def __str__(self):
return f"the value:time is {self.value}:{self.timestamp}"
,schema.py为:
class Query(graphene.ObjectType):
temperature_statistics = graphene.Field(Temperature)
def resolve_temperature_statistics(self, info, **kwargs):
before = kwargs.get("before")
after = kwargs.get("after")
return models.Temperature.objects.filter(created_at__gte=after, created_at__lte=before)
返回一段时间内的最低和最高温度的查询应该如下所示:
query {
temperatureStatistics(after: "2020-12-06T12:00:00+00:00", before: "2020-12-07T12:00:00+00:00") {
min
max
}
}
我不知道如何实现其中的最小和最大部分。
由于在GraphQL查询中使用了min和max,因此我不能只从解析器返回min和max,例如,如果查询是这样编写的,
query {
temperatureMax(after: "2020-12-06T12:00:00+00:00", before: "2020-12-07T12:00:00+00:00")
}
我必须想办法使GraphQL能够完成这项工作。
回应@Ahtisham的评论。以下是我如何实现不带类型的currentTemperature。
schema.py
import graphene
from graphene_django import DjangoObjectType
from temperature import models
class Temperature(DjangoObjectType):
class Meta:
model = models.Temperature
class Query(graphene.ObjectType):
current_temperature = graphene.Field(Temperature)
def resolve_current_temperature(self, info, **kwargs):
return models.Temperature.objects.last()
schema = graphene.Schema(query=Query)
mods.py
from django.db import models
class Temperature(models.Model):
timestamp = models.DateTimeField(auto_now=True)
value = models.FloatField()
这在使用此GraphQL查询进行查询时起作用:
query {
currentTemperature {
timestamp
value
}
}
更新2
我已经根据@Ahtisham的回答更新了schema.py,现在将其作为我的schema.py:
import graphene
from graphene_django import DjangoObjectType
from django.db.models import Max, Min
from temperature import models
class Temperature(DjangoObjectType):
class Meta:
model = models.Temperature
class RangeType(graphene.ObjectType):
min = graphene.String()
max = graphene.String()
class Query(graphene.ObjectType):
current_temperature = graphene.Field(Temperature, id=graphene.Int())
temperature_statistics = graphene.Field(Temperature, before=graphene.String(), after=graphene.String())
def resolve_current_temperature(self, info, **kwargs):
return models.Temperature.objects.latest('timestamp')
def resolve_temperature_statistics(self, info, before=None, after=None):
range_type = RangeType()
if before and after is not None:
range_type.min_ = models.Temperature.objects.filter(created_at__gte=after, created_at__lte=before).aggregate(Min('temperature'))
range_type.max_ = models.Temperature.objects.filter(created_at__gte=after, created_at__lte=before).aggregate(Max('temperature'))
return range_type
elif before is None and after is not None:
range_type.min_ = models.Temperature.objects.filter(created_at__gte=after).aggregate(Min('temperature'))
range_type.max_ = models.Temperature.objects.filter(created_at__gte=after).aggregate(Max('temperature'))
return range_type
elif after is None and before is not None:
range_type.min_ = models.Temperature.objects.filter(created_at__lte=before).aggregate(Min('temperature'))
range_type.max_ = models.Temperature.objects.filter(created_at__lte=before).aggregate(Max('temperature'))
return range_type
else:
range_type.min_ = models.Temperature.objects.aggregate(Min('temperature'))
range_type.max_ = models.Temperature.objects.aggregate(Max('temperature'))
return range_type
schema = graphene.Schema(query=Query)
GraphQL显示此错误
{
"errors": [
{
"message": "Cannot query field "min_" on type "Temperature".",
"locations": [
{
"line": 3,
"column": 7
}
]
},
{
"message": "Cannot query field "max_" on type "Temperature".",
"locations": [
{
"line": 4,
"column": 7
}
]
}
]
}
执行此查询时
query {
temperatureStatistics {
min
max
}
}
更新3
更改后
temperature_statistics = graphene.Field(Temperature, before=graphene.String(), after=graphene.String())
至
temperature_statistics = graphene.Field(RangeType, before=graphene.String(), after=graphene.String())
GraphQL现在显示此错误
{
"errors": [
{
"message": "Cannot resolve keyword 'temperature' into field. Choices are: id, timestamp, value",
"locations": [
{
"line": 2,
"column": 5
}
],
"path": [
"temperatureStatistics"
]
}
],
"data": {
"temperatureStatistics": null
}
}
执行此查询时
query {
temperatureStatistics {
min
max
}
}
同时:
GraphQL显示此错误
{
"errors": [
{
"message": "Cannot resolve keyword 'created_at' into field. Choices are: id, timestamp, value",
"locations": [
{
"line": 2,
"column": 5
}
],
"path": [
"temperatureStatistics"
]
}
],
"data": {
"temperatureStatistics": null
}
}
执行此查询时
query {
temperatureStatistics(after: "2020-12-06T12:00:00+00:00", before: "2020-12-07T12:00:00+00:00")) {
min
max
}
}
更新4
最后一个错误是因为我在Django查询中使用了‘温度’而不是‘值’。现在可以使用了。解决方案
您可以使用MIN和MAX定义一个新类型,然后将其添加到查询中,如下所示:
class RangeType(graphene.ObjectType):
min = graphene.String()
max = graphene.String()
class Query(graphene.ObjectType):
temperature_statistics = graphene.Field(
RangeType, before=graphene.String(), after=graphene.String()
)
def resolve_temperature_statistics(self, info, before=None, after=None):
range_type = RangeType()
range_type.min = # query to get min value
range_type.max = # query to get max value
return range_type
调用查询应该相同。
相关文章