avro架构和生成的文件中的十进制数据类型支持

时间:2017-03-28 11:12:57

标签: java avro

Avro版本1.8.1。

我们在AVRO架构中有以下字段

  

“name”:“sale_price”,“type”:[“bytes”,“null”],“logicalType”:   “十进制”,“精度”:18,“比例”:17,

我们已将logicalType定义为十进制。

但是当我们使用avro-maven-plugin时,它不会生成正确的数据类型,而是生成Java文件。

<plugin>
    <groupId>org.apache.avro</groupId>
    <artifactId>avro-maven-plugin</artifactId>
    <version>1.8.1</version>
    <configuration>
        <stringType>String</stringType>
        <enableDecimalLogicalType>true</enableDecimalLogicalType>
    </configuration>
</plugin>

目前正在生成java.nio.ByteBuffer。 如何获得正确的数据类型是生成Java文件。

3 个答案:

答案 0 :(得分:0)

正如Avro docs解释,

  

语言实现在阅读时必须忽略未知的逻辑类型,并且应使用底层的Avro类型。

     

A decimal logical type注释Avro字节或固定类型。

因此,在生成的Java文件中,十进制逻辑类型以基础Avro类型字节表示,即java.nio.ByteBuffer

答案 1 :(得分:0)

如果要使用BigDecimal,则需要使用1.8.2版,并将enableDecimalLogicalType值的true参数添加到pom文件中:

<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<executions>
    <execution>
        <id>generate-avro-sources</id>
        <phase>generate-sources</phase>
        <goals>
            <goal>schema</goal>
        </goals>
        <configuration>
            <sourceDirectory>${basedir}/src/main/avro/</sourceDirectory>
            <outputDirectory>${basedir}/generated-sources/main/java/</outputDirectory>
            <enableDecimalLogicalType>true</enableDecimalLogicalType>
        </configuration>
    </execution>
</executions>

有关更多信息,请检查以下问题:https://issues.apache.org/jira/browse/AVRO-1847

答案 2 :(得分:0)

我必须执行以下操作。 (因为我找不到任何关于如何设置十进制值的文档,它可能对其他人有帮助)

  1. 定义十进制字段

     {
     "namespace": "com.billionDollarCompany",
     "type": "record",
     "name": "AverageObject",
     "fields": [
       {
         "name": "average",
         "type": {
           "type": "bytes",
           "logicalType": "decimal",
           "precision": 4,
           "scale": 2
         }
       }
     ]
    }
    
  2. 转换 byteBuffer 的十进制数

     public static ByteBuffer ByteBuffer(Schema classSchema, String fieldName, double value)
     {
         LogicalType type = classSchema.getField(fieldName).schema().getLogicalType();
         BigDecimal bigDecimal = new BigDecimal(value, MathContext.DECIMAL32).setScale(((LogicalTypes.Decimal) type).getScale(), BigDecimal.ROUND_HALF_EVEN);
         return ByteBuffer.wrap(bigDecimal.unscaledValue().toByteArray());
     }
    

    什么是规模和精度?

    <块引用>

    小数位数是数字中小数点右边的位数。例如,数字 123.45 的精度为 5,小数位数为 2。