[英]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.