Stream Analytics通过Event Hub从Python反序列化JSON

时间:2016-07-15 08:12:37

标签: python json azure amqp asa

我已经设置了一个Azure Event Hub,我正在从Python脚本发送JSON格式的AMQP消息,并尝试使用Stream Analytics将这些消息流式传输到Power BI。 消息来自IoT设备的非常简单的设备活动

Python代码段是

msg = json.dumps({ "Hub": MAC, "DeviceID": id, "DeviceUID": ouid, "Signal": text, "Timestamp": dtz }, ensure_ascii=False, encoding='utf8')
message.body = msg
messenger.put(message)
messenger.send()

我在MS教程中使用示例C#消息阅读器从事件中心读取数据没有问题,输出为:

Message received.  Partition: '2', Data: '??{"DeviceUID": "z_70b3d515200002e7_0", "Signal": "/on?1", "DeviceID": "1", "Hub": "91754623489", "Timestamp": "2016-07-15T07:56:50.277440Z"}'

但是当我尝试从事件中心测试Stream Analytics输入时,我收到错误

诊断:无法将输入事件反序列化为Json。一些可能的原因:1)格式错误的事件2)输入源配置了错误的序列化格式

我不确定格式错误的事件是什么意思 - 我假设Stream Analytics可以处理通过AMQP发送到事件中心的数据?

我无法看到C#应用程序收到的JSON有什么问题 - 除非BOM符号导致问题?

这是我对这一切的第一次尝试,我搜索过任何类似的帖子都无济于事,所以如果有人能指出我正确的方向,我真的很感激。

干杯 罗布

3 个答案:

答案 0 :(得分:2)

这是由客户端API不兼容引起的。 Python使用Proton在AMQP Value消息的主体中发送JSON字符串。正文被编码为AMQP字符串(AMQP类型编码字节+字符串的utf8编码字节)。 Stream Analytics使用Service Bus .Net SDK,它将AMQP消息公开为EventData,其主体始终为字节数组。对于AMQP值消息,它包括AMQP类型编码字节,因为没有它们,不可能解码以下值。开头的这些额外字节将导致JSON序列化失败。

要实现消息体的互操作性,应用程序应确保发布者和消费者就其类型和编码达成一致。在这种情况下,发布者应该在AMQP数据消息中发送原始字节。使用Proton Python API,您可以尝试:

message.body = msg.encode('utf-8')

另一种解决方法是在应用程序属性中发送简单类型(例如字符串)。

其他人也遇到过这个问题。 https://github.com/Azure/amqpnetlite/issues/117

答案 1 :(得分:0)

正如@XinChen所说,问题是由AMQP协议引起的。

根据我的经验,下面的两种解决方法对于这种情况是有效的。

  1. 使用Send Event REST API代替Azure Python SDK和AMQP,但其余api基于HTTP协议而不是高性能。
  2. 使用Base64编码发送JSON消息,然后将收到的消息解码为JSON字符串。

答案 2 :(得分:0)

这两件事对我有用:

  • 添加message.inferred = True
  • 检查以确保您的指定转储编码encoding='utf-8'而不是encoding='utf8',如您的示例所示。

更新了OP:

msg = json.dumps({ "Hub": MAC, "DeviceID": id, "DeviceUID": ouid, "Signal": text, "Timestamp": dtz }, ensure_ascii=False, encoding='utf-8')
message.body = msg
message.inferred = True
messenger.put(message)
messenger.send()

通过添加推断标志,我认为消息序列化器可以正确地推断出主体是字节并创建AMPQ DATA,从而解决@Xin Chen的问题。

  

消息的推断标志指示消息内容如何编码到AMQP节中。如果推断为真,则消息正文中的二进制和列表值将分别编码为AMQP DATA和AMQP SEQUENCE部分。如果推断为false,则消息正文中的所有值都将被编码为AMQP VALUE部分,而不管其类型如何。

re:Qpid Proton Docs #inferred

re:JSON Encoder and Decoder #dumps