0

嘿 avro 用户和专家,

我想使用 avrologicalTypes,意味着我自己创建一些 - 不仅仅是使用内置的。

问题是如何让编译器从架构生成代码以使用我自己创建的代码

我创建了我的架构(相关部分):

{
  "name": "street",
  "type": {
    "type": "string",
    "logicalType": "custom-street"
  },
  "doc": "Street format ending with house number"
}

(当然还有创建类型和转换,参见https://github.com/markush81/avro-examples

我现在不知道如何配置编译器来使用它

我通过 gradle 插件使用编译器(但我想这首先没有任何区别)

plugins {
    id 'com.commercehub.gradle.plugin.avro' version '0.14.2'
}

avro {
    enableDecimalLogicalType = true //enable built-in decimal type
}

感谢您提供任何提示(或解决方法)。

PS:当然我知道如何操作生成的类来支持我的逻辑类型(见:https ://github.com/markush81/avro-examples/tree/master/src/main/manual ),但这意味着我永远无法从我的模式定义中重新编译。

4

2 回答 2

1

从 Avro 1.9.x 开始,现在可以注册自定义logicalTypeconversion.

重点是写

  • 逻辑类型
  • 逻辑类型工厂
  • 转换

使用 maven 和 gradle 还支持使用您的自定义类型从 avro 模式生成的代码。请参阅https://github.com/markush81/avro-examples中的示例。

Gradle 插件配置

plugins {
    id 'com.commercehub.gradle.plugin.avro' version '0.18.0'
}

avro {
    enableDecimalLogicalType = true
    dateTimeLogicalType = "JSR310"
    stringType = "CharSequence"
    outputCharacterEncoding = "UTF-8"
    logicalTypeFactory("street", de.mh.examples.avro.StreetLogicalTypeFactory)
    customConversion(de.mh.examples.avro.StreetConversion)
}
于 2020-02-23T10:07:55.130 回答
1

avro 代码1.8.2 中进行了大量搜索后,我得出的结论是,目前编译器工具不支持自定义逻辑类型进行代码生成

如果我们看一下record.vm速度模板

#if ($this.hasLogicalTypeField($schema))
    protected static final org.apache.avro.data.TimeConversions.DateConversion DATE_CONVERSION = new org.apache.avro.data.TimeConversions.DateConversion();
    protected static final org.apache.avro.data.TimeConversions.TimeConversion TIME_CONVERSION = new org.apache.avro.data.TimeConversions.TimeConversion();
    protected static final org.apache.avro.data.TimeConversions.TimestampConversion TIMESTAMP_CONVERSION = new org.apache.avro.data.TimeConversions.TimestampConversion();
    protected static final org.apache.avro.Conversions.DecimalConversion DECIMAL_CONVERSION = new org.apache.avro.Conversions.DecimalConversion();

    private static final org.apache.avro.Conversion<?>[] conversions = new org.apache.avro.Conversion<?>[] {
    #foreach ($field in $schema.getFields())
        ${this.conversionInstance($field.schema())},
    #end
       null
    };

    @Override
    public org.apache.avro.Conversion<?> getConversion(int field) {
        return conversions[field];
    }
#end

仅添加了四个转换,由 avro 本身提供。

另一件值得一看的是org.apache.avro.compiler.specific.SpecificCompiler

  public String conversionInstance(Schema schema) {
      if (schema == null || schema.getLogicalType() == null) {
           return "null";
      }

      if (LogicalTypes.date().equals(schema.getLogicalType())) {
           return "DATE_CONVERSION";
      } else if (LogicalTypes.timeMillis().equals(schema.getLogicalType())) {
           return "TIME_CONVERSION";
      } else if (LogicalTypes.timestampMillis().equals(schema.getLogicalType())) {
           return "TIMESTAMP_CONVERSION";
      } else if (LogicalTypes.Decimal.class.equals(schema.getLogicalType().getClass())) {
           return enableDecimalLogicalType ? "DECIMAL_CONVERSION" : "null";
      }

      return "null";
}

也没有可以添加自定义逻辑类型的部分。

于 2018-06-24T07:08:25.073 回答