我无法理解在使用 fastavro(以及常规 avro)转换我的 avro 架构中定义为 float 的数字时遇到的问题。我确信它与我不明白的级别的数据类型存储有关。简而言之,我将一条记录传递到 fastavro.dump,然后将结果传递回 fastavro.load,当值超过 ~9 位数字时,转换不会返回相同的结果。
import fastavro
from io import BytesIO
schema = {
'name': 'Person',
'type': 'record',
'fields': [
{'name': 'EmpName', 'type': 'string'},
{'name': 'ID', 'type': 'float'}]}
origRecord = {'EmpName': 'BillyBob', 'ID': 1111000000}
buf = BytesIO()
fastavro.dump(buf, origRecord, schema)
avroMsg = buf.getvalue()
buf = BytesIO(avroMsg)
afterConversion = fastavro.load(buf, schema)
print(origRecord['ID'])
print(afterConversion['ID'])
输出如下所示:
1111000000
1111000064.0
我预计转换会引入 .0,但值的实际变化让我感到困惑。随着输入值的变化,两者之间的差异也从 -63 到 +64 变化(这可能表明这里实际发生的情况)。就我的测试而言,将架构中的类型更改为 double/long/int 似乎 可以纠正该问题。当使用 float 作为类型时,较小的值不会表现出此行为。
最佳答案
查看avro规范https://avro.apache.org/docs/1.8.1/spec.html
float 被写为 4 个字节。使用相当于Java的floatToIntBits的方法将 float 转换为32位整数,然后以little-endian格式编码。
因此准确性的损失是可以预见的。
关于Python fastavro 错误地转换 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45827782/