【问题标题】:Python 3.4 and AVRO: Unable to convert the simple message in AVRO, based on schema?Python 3.4 和 AVRO:无法根据模式转换 AVRO 中的简单消息?
【发布时间】:2019-07-16 22:42:41
【问题描述】:

我希望使用元数据标头(即嵌套模式)为每条记录 (csv) 创建一条 avro 消息。

我正在使用 Python 3.4。我已经下载了所需的模块,即 avro-python3。 我有带有标题的 csv 格式的记录数据。

基本上我有创建所需消息和元数据标头的代码。

我的 AVSC 文件(仅示例):

Schema: {"name": "person","type": "record","fields": [{"name": "address","type": {"type" : "record","name" : "AddressUSRecord","fields" : [{"name": "streetaddress", "type": "string"},{"name": "city", "type":"string"},{"name": "pin", "type":"long"}]}}]}

我的记录也被创建了。 (显示漂亮的记录格式)。

对于引脚:123.456(浮点值)

但是,当我尝试将上述记录转换为 avro 格式时,基于提到的 avsc 文件,它无法说“Tha datum 不是模式的示例”。

代码:

import avro.schema
from avro.datafile import DataFileReader, DataFileWriter
from avro.io import DatumReader, DatumWriter
import csv
import json
# header class to give header data. Just simple assignment
from header import Header
# body class to give body, just simple assignment for now.
from pnlData import PnlData
import os
import sys

if __name__ == "__main__":
    schemaFile = "/path/tardisPnl.avsc"
    outFile = "/path/SampleOutLanding.avro"
    schema = avro.schema.Parse(open(schemaFile, "r").read())

    a = Header()
    a.generateMessageId() #Simple text generated for now
    a.generateTimestamp() #Simple number generated for now
    #print(a.__dict__)
    b = PnlData()
    b.generatePnlData() #Simple value assigned as seen in example
    #print(b.__dict__)

    landingMessage = {}
    landingMessage["header"] = a.__dict__
    landingMessage["pnlData"] = b.__dict__

    #print (json.dumps(landingMessage))

    writer = DataFileWriter(open(outFile, "wb"), DatumWriter(), schema)
    try:
        writer.append(landingMessage)
    except Exception as e:
        print('Error: %s ' % (e))

    writer.close()

我尝试将上述 avro 模式转换为 JSON 模式,然后基于模式(在线链接)创建示例 JSON 数据,以查看我的数据对象是否正确。事实上,我是根据基于模式生成的示例数据创建记录的。

但是,当我尝试使用它们并运行代码时,它总是失败。

我对 AVRO 不太熟悉,所以需要了解我在这里缺少什么?为什么这个简单的数据和架构不起作用?


我首先尝试了以下简单的记录(相同的示例在线工具)和架构,它可以工作。

简单的avsc:

{"name": "person","type": "record","fields": [{"name": "firstname", "type": "string"},{"name": "lastname", "type": "string"},{"name": "address","type": {"type" : "record","name" : "AddressUSRecord","fields" : [{"name": "streetaddress", "type": "string"},{"name": "city", "type":"string"}]}}]}

简单数据(再次漂亮打印):

{
  "firstname": "ABCDEFGHIJKLMN",
  "lastname": "ABCDEFGHIJKLMNOPQRSTUVWXYZAB",
  "address": {
    "streetaddress": "ABCDEFGHIJKLMN",
    "city": "ABCDEFGHIJKLMNO"
  }
}

如果我创建上面的字典,并将相同的(相同的代码,而不是更改)传递给 avsc 文件,它可以正常工作。

我的 avsc 和(简单)示例 avsc 的唯一区别是一个额外的嵌套属性等。我无法找到不处理我稍微复杂的数据的原因。

【问题讨论】:

    标签: python python-3.x avro


    【解决方案1】:

    fastavro 库有一个 validate 函数可以帮助解决这个问题。

    使用您提供的数据和架构,它看起来像这样:

    schema = {
       "type":"record",
       "name":"SomeName",
       "doc":"This schema contains the metadata fields wrapped in a header field which follows the official SA MessageHeader schema.",
       "fields":[
          {
             "name":"header",
             "type":{
                "type":"record",
                "name":"MessageHeader",
                "fields":[
                   {
                      "name":"messageId",
                      "type":"string"
                   },
                   {
                      "name":"businessId",
                      "type":"string"
                   },
                   {
                      "name":"batchId",
                      "type":"string"
                   },
                   {
                      "name":"sourceSystem",
                      "type":"string"
                   },
                   {
                      "name":"secondarySourceSystem",
                      "type":"string"
                   },
                   {
                      "name":"sourceSystemCreationTimestamp",
                      "type":"long"
                   },
                   {
                      "name":"sentBy",
                      "type":"string"
                   },
                   {
                      "name":"sentTo",
                      "type":"string"
                   },
                   {
                      "name":"messageType",
                      "type":"string"
                   },
                   {
                      "name":"schemaVersion",
                      "type":"string"
                   },
                   {
                      "name":"processing",
                      "type":"string"
                   },
                   {
                      "name":"sourceLocation",
                      "type":"string"
                   }
                ]
             }
          },
          {
             "name":"pnlData",
             "type":{
                "type":"record",
                "name":"pnlDataDetails",
                "fields":[
                   {
                      "name":"granularity",
                      "type":"string"
                   },
                   {
                      "name":"pnl_type",
                      "type":"string"
                   },
                   {
                      "name":"pnl_subtype",
                      "type":"string"
                   },
                   {
                      "name":"date",
                      "type":"int"
                   },
                   {
                      "name":"book",
                      "type":"string"
                   },
                   {
                      "name":"currency",
                      "type":"string"
                   },
                   {
                      "name":"category",
                      "type":"string"
                   },
                   {
                      "name":"subcategory",
                      "type":"string"
                   },
                   {
                      "name":"riskcategory",
                      "type":"string"
                   },
                   {
                      "name":"market_name",
                      "type":"string"
                   },
                   {
                      "name":"risk_order",
                      "type":"string"
                   },
                   {
                      "name":"tenor",
                      "type":"string"
                   },
                   {
                      "name":"product",
                      "type":"string"
                   },
                   {
                      "name":"trade_id",
                      "type":"string"
                   },
                   {
                      "name":"pnl_local",
                      "type":"long"
                   },
                   {
                      "name":"pnl_cde",
                      "type":"long"
                   },
                   {
                      "name":"pnl_status",
                      "type":"string"
                   }
                ]
             }
          }
       ]
    }
    
    record = {
        "pnlData": {
            "pnl_cde": 997.8100000024,
            "pnl_status": "locked",
            "granularity": "detailed view",
            "book": "8271",
            "date": 20181130,
            "subcategory": "None",
            "pnl_local": 997.7899999917,
            "pnl_subtype": "Regular",
            "tenor": "None",
            "pnl_type": "Daily",
            "risk_order": "None",
            "market_name": "None",
            "trade_id": "None",
            "category": "None",
            "product": "None",
            "currency": "cad",
            "riskcategory": "None"
        },
        "header": {
            "sentBy": "SYSTEM",
            "businessId": "T1",
            "messageId": "pnl_0001",
            "processing": "RealTime",
            "messageType": "None",
            "sourceLocation": "None",
            "sentTo": "SA",
            "secondarySourceSystem": "None",
            "schemaVersion": "1.6T",
            "sourceSystem": "SYSTEM",
            "sourceSystemCreationTimestamp": 1236472051,
            "batchId": "None"
        }
    }
    
    import fastavro
    
    fastavro.validation.validate(record, schema)
    

    我得到的错误如下:"SomeName.pnlData.pnlDataDetails.pnl_local is <997.7899999917> of type <class 'float'> expected long"

    【讨论】:

    • 感谢@Scott 指出问题。请注意,我已经编辑了架构以删除机密数据(之前错过了)。了解 long vs float 的问题。谢谢。
    猜你喜欢
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 2016-11-10
    • 2016-12-27
    • 1970-01-01
    相关资源
    最近更新 更多