【问题标题】:Nesting Avro schemas嵌套 Avro 模式
【发布时间】:2017-04-12 18:41:46
【问题描述】:

根据this question关于嵌套 Avro 模式,嵌套记录模式的正确方法如下:

{
    "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"}
                        ]
                    },
        }
    ]
}

我不喜欢给字段命名为 address 并且不得不为字段的架构提供不同的名称 (AddressUSRecord)。我可以为字段和架构提供相同的名称address吗?

如果我想在多个其他模式中使用AddressUSRecord 模式,而不仅仅是person,该怎么办?如果我想在另一个架构中使用AddressUSRecord,比如说business,我是否必须将其命名为其他名称?

理想情况下,我想在单独的架构中定义AddressUSRecord,然后让address 的类型引用AddressUSRecord。但是,尚不清楚 Avro 1.8.1 是否支持这种开箱即用。这个2014 article 表明需要使用自定义代码处理子模式。在 Avro 1.8.1 中定义可重用模式的最佳方法是什么?

注意:我想要一个可以与 Confluent Inc. 的 Schema Registry 配合使用的解决方案。有一个Google Groups thread 似乎表明架构注册表不能很好地处理架构引用。

【问题讨论】:

    标签: nested schema record avro


    【解决方案1】:

    我可以为字段和架构指定相同的名称、地址吗?

    是的,您可以将记录命名为与字段名称相同的名称。

    如果我想在多个其他模式中使用 AddressUSRecord 模式,而不仅仅是人呢?

    您可以使用多种技术使用多个模式:avro 模式解析器客户端(JVM 和其他)允许您指定多个模式,通常通过 names 参数(Java Schema$Parser/parse 方法允许多个模式 @987654324 @参数)。

    然后您可以将依赖模式指定为命名类型:

    {
      "type": "record",
      "name": "Address",
      "fields": [
        {
          "name": "streetaddress",
          "type": "string"
        },
        {
          "name": "city",
          "type": "string"
        }
      ]
    }
    

    并在父模式之前通过解析器运行它:

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

    顺便说一句,这允许您从单独的文件中进行解析。

    或者,您还可以解析以相同方式引用模式的单个联合模式:

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

    我想要一个可以与 Confluent Inc. 的 Schema Registry 配合使用的解决方案。

    架构注册表不支持单独解析架构,但它确实支持解析为联合类型的后一个示例。

    【讨论】:

    • 嗨 Niel,我在融合云上尝试完全相同的架构,但是当我在生产者中调用此架构时,我无法使用此架构,即“xxxx.eu-central-1.aws.confluent.cloud" --api-key "xx" --api-secret "xxxxx" 启动 Kafka Producer。 ^C 或 ^D 退出 {"firstname": "Joe", "lastname": "Doe", "address": {"streetaddress": "somestreet", "city": "somecity"}} 错误:无法解码文本联合:无法解码文本映射:无法确定编解码器:“名字”
    • 您的 JSON 数组模式确实通过了 avro 验证,但如何使用它?适用于 JSON 对象模式的生产者调用语法不适用于您的提案。谢谢
    【解决方案2】:

    您可以将namespace 设置为记录类型,然后在后续字段中使用{namespace}.{name} 作为type 参数。不幸的是,目前无法从其他模式文件中引用类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-23
      • 2012-07-30
      • 2018-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      相关资源
      最近更新 更多