[英]How can a org.apache.kafka.connect.data.Decimal stored in an avro file be converted to a python type?
我正在尝试使用Python解释Debezium在Kafka中存储的Avro记录
{
"name": "id",
"type": {
"type": "bytes",
"scale": 0,
"precision": 64,
"connect.version": 1,
"connect.parameters": {
"scale": "0"
},
"connect.name": "org.apache.kafka.connect.data.Decimal",
"logicalType": "decimal"
}
}
我不确定这对应于哪个 Python 3 原始类型。 这个值如何反序列化?
提前致谢!
如果你看
public static byte[] fromLogical(Schema schema, BigDecimal value) {
if (value.scale() != scale(schema))
throw new DataException("BigDecimal has mismatching scale value for given Decimal schema");
return value.unscaledValue().toByteArray();
}
如您所见,它使用 BigDecimal,相当于 Python 中的Decimal
Java 的 BigDecimal 的 python 是什么?
因此,在这种情况下,您应该寻找 Decimal。
第 2 部分 - 反序列化
关于反序列化,我需要反馈来更新答案。 到目前为止,您如何在其他领域做到这一点?
org.apache.kafka.connect.data.Decimal
是未缩放整数的 base64 编码字节表示。 为了将此值转换为Decimal
,您需要将 base64 字符串解码为字节,获取整数,然后通过parameters.scale
值对其进行缩放。
这个架构:
{
"type": "bytes",
"name": "org.apache.kafka.connect.data.Decimal",
"version": 1,
"parameters": {
"scale": "9",
"connect.decimal.precision": "38"
},
"field": "amount"
}
ctx = decimal.Context()
ctx.prec = 38 # connect.decimal.precision = 38
result = ctx.create_decimal(
int.from_bytes(base64.b64decode("GZ6ZFQvYpA=="), byteorder='big')
) / 10 ** 9 # scale = 9
当我对负数使用其他答案时,它会给出错误的结果。 例如 -20.62 数字被 debezium 转换为“+CA=”到 kafka
我从下面的链接中找到了解决方案,然后像这样更改。
import decimal
import base64
def big_decimal_to_decimal(big_decimal, scale, precision):
bytes_val = base64.decodebytes(big_decimal.encode())
bval = "".join("{0:08b}".format(c) for c in bytes_val)
intval = int(bval, 2)
if bytes_val[0] & 0x70 != 0:
intval -= int('1' + '00' * len(bytes_val), 16)
return intval/(10**scale)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.