создать представление json для десятичного логического типа и типов байтов для схемы avro

Я пытаюсь создать строку JSON в соответствии с приведенной ниже схемой avro для десятичного значения. https://avro.apache.org/docs/1.8.2/spec.html#Logical+Types

{
 "name": "score",
 "type": "bytes",
 "logicalType": "decimal",
 "precision": 10,
 "scale": 5
 }

ценность

"score":3.4,

я получаю исключение

Caused by: org.apache.avro.AvroTypeException: Expected bytes. Got VALUE_NUMBER_FLOAT.

Вместо 3.4, если я укажу "\ u0000", тогда это сработает, но это представление 0, как я получу представление для 3.4? На данный момент я создаю жестко закодированную строку JSON, но в будущем мне нужно преобразовать вывод в десятичный формат, как я могу сделать это в scala.

Есть ли способ преобразовать значение в десятичный логический формат?


person Kalpesh    schedule 18.09.2019    source источник
comment
Вы нашли решение? Я столкнулся с аналогичной проблемой: stackoverflow.com/questions/60623764/   -  person vdep    schedule 10.03.2020
comment
да, к сожалению, у меня нет с собой этого кода. Я преобразовал значение в байтовый формат, просто найдите преобразование с плавающей запятой в байтовый формат, и я думаю, что это должно работать.   -  person Kalpesh    schedule 11.03.2020
comment
если бы вы могли найти этот код, это было бы потрясающе   -  person vanillaSugar    schedule 06.05.2020


Ответы (1)


Java-код:

byte[] score = new BigDecimal("3.40000").unscaledValue().tobyteArray();
for (byte b : score) {​
    System.out.println(String.format("\\u%04x", b));
}

Распечатает следующее:

\u00fa
\u00cf
\u00e0

Затем вам нужно написать значение оценки json следующим образом:

"score":"\u00fa\u00cf\u00e0",

И это должно перевести на 3.40000. Причина, по которой 3.40000, заключается в том, что 'масштаб' в вашей схеме имеет значение 5. Если бы масштаб имел значение 2, то у нас был бы новый BigDecimal("3.40")

Функция Scala для преобразования BigDecimal в json, чтобы avro это понял

def toJsonString(value: java.math.BigDecimal): String = {
    val bytes = value.unscaledValue().toByteArray
    bytes
      .map(_.formatted("\\u%04x"))
      .mkString
}
person vanillaSugar    schedule 11.05.2020