Avro не заполняет квадратные скобки для типа Array - PullRequest
0 голосов
/ 16 октября 2018

У меня есть следующая схема 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 был заключен в квадратные скобки.Как мне этого добиться?

1 Ответ

0 голосов
/ 17 октября 2018

У вас есть два элемента в записи с именем 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"}
...