Avro 使用 Java 8 日期作为逻辑类型

2022-09-01 23:29:08

最新的Avro编译器(1.8.2)使用基于Joda-Time的实现为日期逻辑类型生成java源。如何配置 Avro 编译器以生成使用 Java 8 日期时间 API 的源代码?


答案 1

目前(avro 1.8.2)这是不可能的。它是硬编码的,可以生成Joda日期/时间类。

当前分支已切换到 Java 8,并且存在一个未解决的问题(使用拉取请求),以添加生成具有类型的类的功能。masterjava.time.*

不幸的是,我不知道目前有什么发布时间表。如果您喜欢冒险,则可以将补丁应用于 ,因为从理论上讲,它应该都是兼容的。序列化/反序列化时的基础基类型仍然是整数和长整型。master1.8.2


答案 2

您需要创建自己的转换s 来支持 java-8 日期时间 api,下面是一个转换:java.time.LocalDate

class Java8LocalDateConversion extends Conversion<LocalDate> {
    @Override
    public Class<LocalDate> getConvertedType() {
        return LocalDate.class;
    }

    @Override
    public String getLogicalTypeName() {
        //      v--- reuse the logical type `date`
        return "date";
    }

    @Override
    // convert LocalDate to Integer
    public Integer toInt(LocalDate value, Schema schema, LogicalType type) {
        return (int) value.toEpochDay();
    }

    @Override
    // parse LocalDate from Integer
    public LocalDate fromInt(Integer value, Schema schema, LogicalType type) {
        return LocalDate.ofEpochDay(value);
    }
}

逻辑类型可以在 avro 中重用,因此您可以使用现有的逻辑类型,例如:date

Schema schema = LogicalTypes.date().addToSchema(Schema.create(Type.INT));

对于序列化和反序列化,您应该设置这将找到您自己的转换,例如:GenericData

//serializing
DatumWriter<T> out = new SpecificDatumWriter<>(schema, data());

// deserializing
DatumReader<T> in = new SpecificDatumReader<>(schema, schema, data());

private SpecificData data() {
    SpecificData it = new SpecificData();
    it.addLogicalTypeConversion(new Java8LocalDateConversion());
    return it;
}

如果不想每次都配置 ,则可以改用全局,例如:GenericDataGenericData

//      register the conversion globally ---v
SpecificData.get().addLogicalTypeConversion(new Java8LocalDateConversion());

推荐