Avro Java API Timestamp Logical Type?
Asked Answered
A

3

13

With the Avro Java API, I can make a simple record schema like:

    Schema schemaWithTimestamp = SchemaBuilder
            .record("MyRecord").namespace("org.demo")
            .fields()
            .name("timestamp").type().longType().noDefault()
            .endRecord();

How do I tag a schema field with a logical type, specifically: https://avro.apache.org/docs/1.8.1/api/java/org/apache/avro/LogicalTypes.TimestampMillis.html

Affianced answered 28/3, 2017 at 22:12 Comment(0)
A
23

Thanks to DontPanic:

    Schema timestampMilliType = LogicalTypes.timestampMillis().addToSchema(Schema.create(Schema.Type.LONG));

    Schema schemaWithTimestamp = SchemaBuilder
            .record("MyRecord").namespace("org.demo")
            .fields()
            .name("timestamp_with_logical_type").type(timestampMilliType).noDefault()
            .name("timestamp_no_logical_type").type().longType().noDefault()
            .endRecord();

    System.out.println(schemaWithTimestamp.toString(true));

This results in:

{
  "type" : "record",
  "name" : "MyRecord",
  "namespace" : "org.demo",
  "fields" : [ {
    "name" : "timestamp_with_logical_type",
    "type" : {
      "type" : "long",
      "logicalType" : "timestamp-millis"
    }
  }, {
    "name" : "timestamp_no_logical_type",
    "type" : "long"
  } ]
}
Affianced answered 29/3, 2017 at 19:19 Comment(2)
In which package i can find LogicalTypes? what should i import for this?Unity
It's in the standard Avro library at Maven Coordinates "org.apache.avro:avro:1.8.2" import org.apache.avro.LogicalTypesAffianced
L
7

Thanks for the first solution, now for nullable logicalType like:

{ 
"name":"maturityDate",
  "type":["null", {
    "type":"long","logicalType":"timestamp-millis"
    }]
},

I figure the following:

        Schema timestampMilliType = LogicalTypes.timestampMillis().addToSchema(Schema.create(Schema.Type.LONG));

        Schema clientIdentifier = SchemaBuilder.record("ClientIdentifier")
                .namespace("com.baeldung.avro")
                .fields()
                .requiredString("hostName")
                .requiredString("ipAddress")
                .name("maturityDate")
                .type()
                .unionOf()
                .nullType()
                .and()
                .type(timestampMilliType)
                .endUnion()
                .noDefault()
                .endRecord();
Litigable answered 10/5, 2019 at 22:39 Comment(1)
Been searching this for so long. Truly appreciatedTalca
C
2

I think you may create schema manually:

List<Schema.Field> fields = new ArrayList<>();
Schema timeStampField = Schema.create(Schema.Type.LONG);
fields.add(new Schema.Field("timestamp", LogicalTypes.timestampMillis().addToSchema(timeStampField), null, null));
Schema resultSchema = Schema.createRecord("MyRecord", null, "org.demo", false, fields);
System.out.println(resultSchema);

your schema:

{"type":"record","name":"MyRecord","namespace":"org.demo","fields":[{"name":"timestamp","type":"long"}]}

resultSchema with timestampMillis:

{"type":"record","name":"MyRecodr","namespace":"org.demo","fields":[{"name":"timestamp","type":{"type":"long","logicalType":"timestamp-millis"}}]}
Cutch answered 29/3, 2017 at 18:15 Comment(2)
Your code works. However, this does work with the much cleaner SchemaBuilder fluent API. I posted this in a separate answer. Thank you!Affianced
Glad that helped)Cutch

© 2022 - 2024 — McMap. All rights reserved.