在模式不同的Python Graphene中执行嵌套查询

时间:2019-08-01 16:09:34

标签: graphql graphene-python

我有一个来自数据库的以下数据结构:

[
   {
    'time': '2019-07-19T12:57:17Z', 
    'bizLocation': 'urn:epc:id:sgln:bizLocation.Company.3',
    'city': 'dallas',
    'countryCode': 'US',
    'humid': 49, 
    'sID': '40:61:32:22:11:00',
    'site': 'factory',
    'stype': 'BME280',
    'temp': 22.941
   }
]

我希望创建一个GraphQL API来查询数据库并在以下输出中提供查询:

[
{
   sID: String (same as sID),
   sType: String (same as sType),
   bizLocation: String (same as bizLocation),
   values: [
       {
         timestamp: Datetime (same as time),
         value: Float (value of 'temp')
         mType: 'temp'
       },
       {
         timestamp: Datetime (same as time),
         value: Float (value of 'humid'),
         mType: 'humid'
       }
   ]
}
]

我正在使用Graphene来测试它是否可行。目前,我只是在考虑这个想法,并尝试制作以下GraphQL模式:

type SensorDoc {
   sID: String
   sType: String
   bizLocation: String
   values: [SensorData]
}

type SensorData {
   timestamp: String
   value: Float
   mType: String
}

翻译成石墨烯的方法如下:

import graphene

class SensorData(graphene.ObjectType):
    timestamp = graphene.DateTime()
    value = graphene.Float()
    mType = graphene.String()

class SensorDoc(graphene.ObjectType):
    sId = graphene.String()
    sType = graphene.String()
    bizLocation = graphene.String()
    values = graphene.List(SensorData)

class Query(graphene.ObjectType):

    sensor_data = graphene.List(SensorDoc)
    def resolve_sensor_data(self, info):
        # DB Query Logic Here!!

        output = [] # output to return

        for each_point in list_result:
            SensorDoc(sId=each_point['sID'], sType=each_point['stype'], 
                bizLocation=each_point['bizLocation'],
                SensorData(timestamp=each_point['time'], 
    value=each_point['humid'], mType='humid') # <---- This is a SyntaxError
            )

            output.append(SensorDoc)
        return output

由于SensorData不会作为关键字参数传递,因此无法使用。

我对尝试使用石墨烯完全陌生,并且想知道当查询看起来如下时如何实现:

query{
   sensorData {
       sID
       sType
       bizLocation
       values {
          timestamp
          value
       }
   }
}

1 个答案:

答案 0 :(得分:2)

我能够通过解决values类中的SensorDoc来解决此问题:

class SensorData(graphene.ObjectType):
    timestamp = graphene.String()
    temp = graphene.Float()
    humid = graphene.Float()


class SensorDoc(graphene.ObjectType):
    sId = graphene.String()
    sType = graphene.String()
    bizLocation = graphene.String()
    values = graphene.List(SensorData)

    def resolve_values(parent, info):
        # DB Query Logic
        output = [] # output to return

        for each_point in list_result:
            output.append(
               SensorData(timestamp=each_point['time'], temp=each_point['temp'], humid=each_point['humid'])
            )
        return output

在主Query类中,保留resolve_sensor_doc解析器:

class Query(graphene.ObjectType):
    sensor_doc = graphene.List(SensorDoc)

    def resolve_sensor_doc(self, info):
        # DB Query Logic

        output = []
        for each_point in list_result:
            output.append(
                SensorDoc(
                    sId=each_point['sID'], 
                    sType=each_point['stype'], 
                    bizLocation=each_point['bizLocation']
                )
            )
        return output

最后执行:

schema = graphene.Schema(query=Query)

result = schema.execute(
    '''
    query {
        sensorDoc{
            sId
            sType
            bizLocation
            values {
                timestamp
                temp
                humid
            }
        }
    }
    '''
)

items = dict(result.data.items())
print(json.dumps(items, indent=4))

向我提供如下输出:

{
    "sensorDoc": [
        {
            "sId": "60:64:05:9C:DF:F2",
            "sType": "BME280",
            "bizLocation": "urn:epc:id:sgln:bizLocation.3",
            "values": [
                {
                    "timestamp": "2019-07-19T12:57:17Z",
                    "temp": 22.941,
                    "humid": 49.0
                },
                {
                    "timestamp": "2019-07-19T12:57:19Z",
                    "temp": 22.981,
                    "humid": 47.0
                },
                {
                    "timestamp": "2019-07-19T12:57:21Z",
                    "temp": 23.001,
                    "humid": 47.0
                }
            ]
        },
        {
            "sId": "60:64:05:9C:DF:F2",
            "sType": "BME280",
            "bizLocation": "urn:epc:id:sgln:bizLocation.3",
            "values": [
                {
                    "timestamp": "2019-07-19T12:57:17Z",
                    "temp": 22.941,
                    "humid": 49.0
                },
                {
                    "timestamp": "2019-07-19T12:57:19Z",
                    "temp": 22.981,
                    "humid": 47.0
                },
                {
                    "timestamp": "2019-07-19T12:57:21Z",
                    "temp": 23.001,
                    "humid": 47.0
                }
            ]
        },
        {
            "sId": "60:64:05:9C:DF:F2",
            "sType": "BME280",
            "bizLocation": "urn:epc:id:sgln:bizLocation.3",
            "values": [
                {
                    "timestamp": "2019-07-19T12:57:17Z",
                    "temp": 22.941,
                    "humid": 49.0
                },
                {
                    "timestamp": "2019-07-19T12:57:19Z",
                    "temp": 22.981,
                    "humid": 47.0
                },
                {
                    "timestamp": "2019-07-19T12:57:21Z",
                    "temp": 23.001,
                    "humid": 47.0
                }
            ]
        }
    ]
}