![](/img/trans.png)
[英]How to serialize timestamp-millis logicalType to avro file using java
[英]Write avro files with LogicalType 'timestamp-millis' on date/timestamps in Java Beam pipeline
我有幾個管道從流式 JSON 記錄寫入 avro 文件,但是我在將它們導入 BigQuery 時遇到問題,因為日期字段的logicalType 未在 avro 架構中定義。
考慮以下簡單的 PoJo:
@DefaultCoder(AvroCoder.class)
public class SampleClass {
@AvroEncode(using=DateAsLongEncoding.class)
private Date updateTime;
public SampleClass() {
}
// Getters and setters
}
使用它,該字段可以正確地保存到 avro。 但是,未在架構中設置 LogicalType,當您希望它是TIMESTAMP
或DATE
而不是 long 時,在導入 BigQuery 時會導致問題。
我希望能夠注釋字段,就像使用@AvroEncode
。 設置@LogicalType('timestamp-millis')
會很好。
有沒有人完成過類似的事情,或者有任何其他簡單的方法來為字段指定 LogicalType?
這是使用 gson typeAdapters 來解決的,用於反序列化傳入的 json,如下所示:
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Sample.class, new JsonDeserializer() {
@Override
public Sample deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
JsonObject jObj = json.getAsJsonObject();
return new Sample(
jObj.get("timestamp").getAsString()
);
}
catch (Exception e) {
log.error("Sample parser failed" + e.toString());
return null;
}
}
});
builder.create();
示例 class,使用 java.time.Instant 從 ISO 日期字符串創建毫秒:
@DefaultCoder(SnappyCoder.class)
public class Sample implements Serializable {
@AvroSchema("{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}")
private long updateTime;
public Sample(String timestamp) {
this.updateTime = Instant.parse(timestamp).toEpochMilli();
}
}
您可以嘗試在此測試中指定@AvroSchema
所以您的示例看起來像
@DefaultCoder(AvroCoder.class)
public class SampleClass {
@AvroEncode(using=DateAsLongEncoding.class)
@AvroSchema("{\"type\": \"long\", \"logicalType\": \"timestamp-millis\"}")
private Date updateTime;
public SampleClass() {
}
// Getters and setters
}
也有考慮過用BigQueryIO直接寫嗎? 它有兩種寫方法,一種寫出文件並加載它們,另一種使用流插入API。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.