【问题标题】:Avro not populating square brackets for Array typeAvro 没有为 Array 类型填充方括号
【发布时间】:2019-03-21 10:03:01
【问题描述】:

我有以下 Avro 架构:

{
"name": "schema_name",
"type": "record",
"fields" : [
{
"name": "schema",
"type": "string"
},
{
  "name": "data",
  "type": {
    "type": "array",
    "items":
      {
        "name": "data",
        "type": "record",
        "fields": [
          {
            "name": "phone_number",
            "type": "string"
          }
        ]
      }
  }
},
{
  "name":"flag",
  "type":"string"
}
]
}

我正在使用它从文本文件中生成 Avro 消息:

def main(args: Array[String]): Unit = {
  val avroSchemaStr = Source.fromFile("avro_schema.txt").mkString
  val avroSchema = new Schema.Parser().parse(avroSchemaStr)

  Source.fromFile("phone_numbers.txt").getLines.foreach { msg =>
    println(fixedWidthToAvro(msg, avroSchema))
  }
}

def fixedWidthToAvro(record: String, avroSchema: Schema): GenericRecord = {
  val childSchema = new GenericData.Record(avroSchema).getSchema.getField("data").schema.getElementType
  val parentRrecord = new GenericData.Record(avroSchema)
  val childRecord = new GenericData.Record(childSchema)

  childRecord.put("phone_number", "1234567890")
  parentRrecord.put("schema", "schema_name")
  parentRrecord.put("data", childRecord)
  parentRrecord.put("flag", "I")

  println(parentRrecord)
  parentRrecord
}

一切正常,我得到给定消息的以下输出:

{"schema": "schema_name", "data": {"phone_number": "1234567890"}, "flag": "I"}

但是,当我将 data 字段类型声明为 array 时,我希望它像集合一样包含在方括号中。比如:

{"schema": "schema_name", "data": [{"phone_number": "1234567890"}], "flag": "I"}

我希望将 data 归档在方括号中。我怎样才能做到这一点?

【问题讨论】:

    标签: scala avro avro4s


    【解决方案1】:

    记录中有两个名为data 的元素。一个是数组,另一个是数组里面的元素名,我觉得这就是让你困惑的地方。

    当您将schema.getElementType 传递给Record 时,您正在生成一条记录,而忽略了创建一个Array[Record] 来保存所有这些记录。

    您需要的是一个能够容纳所有记录的数组:

    val avroSchema = new Schema.Parser().parse(schema)
    val childSchema = new GenericData.Record(avroSchema).getSchema.getField("data").schema
    
    val parentRecord = new GenericData.Record(avroSchema)
    val childRecords = new GenericData.Array[GenericData.Record](1024, childSchema)
    
    val childRecord = new GenericData.Record(childSchema.getElementType)
    
    childRecord.put("phone_number", "33333")
    childRecords.add(childRecord)
    
    parentRecord.put("schema", "schema_name")
    parentRecord.put("data", childRecords)
    parentRecord.put("flag", "I")
    
    println(parentRecord)
    

    产量:

    {"schema": "schema_name", "data": [{"phone_number": "33333"}], "flag": "I"}
    

    【讨论】:

    • 太棒了,它成功了,感谢您的详细描述和解决方案。
    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多