I am trying to create JSON string as per below avro schema, for decimal value. https://avro.apache.org/docs/1.8.2/spec.html#Logical+Types
{
"name": "score",
"type": "bytes",
"logicalType": "decimal",
"precision": 10,
"scale": 5
}
value
"score":3.4,
I am getting exception
Caused by: org.apache.avro.AvroTypeException: Expected bytes. Got VALUE_NUMBER_FLOAT.
Instead of 3.4 if I give "\u0000" then it works but this is representation of 0, how I will get representation for 3.4? For now I am creating hard-coded JSON String, but in future I have to convert output into Decimal, how I can do that in scala.
Is there any way to convert value into decimal logical format?
Avro allows arrays of supported basic types, except: String. Decimal.
Avro supports logical types. A logical type is defined as a higher level representation for a primitive type. For eg, a higher level type of UUID could be represented as a primitive type string. Similarly, a higher level java. time.
There are two data serialization formats which Avro supports: JSON format and Binary format.
Java code:
byte[] score = new BigDecimal("3.40000").unscaledValue().tobyteArray();
for (byte b : score) {
System.out.println(String.format("\\u%04x", b));
}
Will print out following:
\u00fa
\u00cf
\u00e0
You then need to write json score value like this:
"score":"\u00fa\u00cf\u00e0",
And it should translate to 3.40000. The reason why 3.40000 is because 'scale' in your schema has value 5. If scale would have value 2, then we would have new BigDecimal("3.40")
Scala function for converting BigDecimal to json so avro will understand it
def toJsonString(value: java.math.BigDecimal): String = {
val bytes = value.unscaledValue().toByteArray
bytes
.map(_.formatted("\\u%04x"))
.mkString
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With