【问题标题】:How to get Avro schema validation to support field aliases?如何获得 Avro 模式验证以支持字段别名?
【发布时间】:2019-09-03 10:57:28
【问题描述】:

我已在使用 Avro 序列化的记录中重命名了一个字段。我想支持读取旧版本的数据,而不需要模式注册表。因此,我将架构的所有版本都保留为从类路径加载的资源。

这很好用并且支持模式演变。当它们向后兼容时,我可以读取使用旧模式序列化的数据。作为确保这一点的一部分,我想在应用程序启动时验证模式。不幸的是,模式验证不支持字段别名,即使解码数据支持。

这里有一个简单的例子来证明我的观点:

import java.util.Collections;

import org.apache.avro.Schema;
import org.apache.avro.SchemaBuilder;
import org.apache.avro.SchemaValidationException;
import org.apache.avro.SchemaValidatorBuilder;


public class Bar {
    public static void main(String[] args) throws SchemaValidationException {
        Schema stringType = SchemaBuilder.builder().stringType();
        Schema s1 = SchemaBuilder.builder().record("foo").fields()
                .name("test1").type(stringType).noDefault()
                .endRecord();
        Schema s2 = SchemaBuilder.builder().record("foo").fields()
                .name("test2").aliases("test1").type(stringType).noDefault()
                .endRecord();

        new SchemaValidatorBuilder().canReadStrategy().validateLatest().validate(s2, Collections.singleton(s1));

    }
}

这会引发以下异常:

Exception in thread "main" org.apache.avro.SchemaValidationException: Unable to read schema: 
{
  "type" : "record",
  "name" : "foo",
  "fields" : [ {
    "name" : "test1",
    "type" : "string"
  } ]
}
using schema:
{
  "type" : "record",
  "name" : "foo",
  "fields" : [ {
    "name" : "test2",
    "type" : "string",
    "aliases" : [ "test1" ]
  } ]
}
    at org.apache.avro.ValidateMutualRead.canRead(ValidateMutualRead.java:70)
    at org.apache.avro.ValidateCanRead.validate(ValidateCanRead.java:40)
    at org.apache.avro.ValidateLatest.validate(ValidateLatest.java:51)
    at Bar.main(Bar.java:18)

【问题讨论】:

    标签: java schema avro


    【解决方案1】:

    很抱歉回答我自己的问题:

    我在 Arvo 用户邮件列表中发现了这个问题的一个变体,但没有得到回答。 Different behavior between SchemaValidator and SchemaCompatibility regarding aliased field

    在我看来,SchemaValidator 有一个错误,但我不明白为什么会有 SchemaValidator 和 SchemaCompatibility 所以感觉就像我失踪了 东西。

    简而言之,使用SchemaCompatibility.checkReaderWriterCompatibility 而不是SchemaValidatorBuilder,它会更完整并重用解码逻辑。

    【讨论】:

      猜你喜欢
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      • 2020-03-18
      • 2020-08-04
      • 2019-12-10
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多