【问题标题】:Apache Avro generates wrong Avro schema from Java POJO with @AvroSchemaApache Avro 使用 @AvroSchema 从 Java POJO 生成错误的 Avro 模式
【发布时间】:2020-11-26 12:06:33
【问题描述】:

我有一个带日期的简单 POJO,在导入到 Google BigQuery 之前,它将作为 Avro 存储在存储中。日期转换为长日期,我正在尝试使用 @AvroSchema 覆盖日期字段的架构生成,以便 BigQuery 了解这些字段的类型。

简单的 POJO:

public class SomeAvroMessage implements Serializable {
    @AvroSchema("{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}")
    private long tm;
    @AvroSchema("{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}")
    private long created;

    public SomeAvroMessage() {
    }
}

最终得到以下 AVRO 模式:

{"type":"record","name":"SomeAvroMessage",
"namespace":"some.namespace",
"fields":[
      {"name":"tm","type":{"type":"long","logicalType":"timestamp-millis"}},
      {"name":"created","type":{"type":"long","logicalType":"timestamp-millis"}}
]}

这些似乎是错误的,应该只是 {"name":"tm","type":"long","logicalType":"timestamp-millis"}

这用于 Google Dataflow,Apache Beam 2.22 是用 Java 编写的。

我错过了什么吗?

【问题讨论】:

  • 是什么让你觉得它错了?架构是有效的架构
  • 是的,根据我的回答,这是一个有效的架构。但它是否会以某种方式造成问题?

标签: google-cloud-dataflow apache-beam avro


【解决方案1】:

{"name":"tm","type":{"type":"long","logicalType":"timestamp-millis"}} 的值是正确的。如果我们把它展开成更清晰的伪代码,那就是:

Field {
  name: "tm",
  type: Schema {
    type: "long",
    logicalType: "timestamp-millis"
  }
}

您可以看到该字段有一个name 和一个type。 Avro 字段的type 必须是 Avro 模式。 logicalType 字段位于架构内部,而不是与其相邻。

【讨论】:

  • 谢谢大家,看来我没有阅读足够好的规格!
【解决方案2】:

可以在documentation中找到:

逻辑类型是 Avro 原始类型或复杂类型,带有额外的 属性来表示派生类型。属性logicalType 必须 始终存在于逻辑类型,并且是名称为的字符串 本节后面列出的逻辑类型之一。其他 可以为特定的逻辑类型定义属性。

该文档还提供了 avro 模式中日期类型的示例:

{
  "type": "int",
  "logicalType": "date"
}

基本上你的模式是正确的,每次你需要使用一些逻辑类型时,你都可以像这样构建你的模式。

【讨论】:

    猜你喜欢
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    • 2014-08-24
    • 2019-11-22
    相关资源
    最近更新 更多