繁体   English   中英

使用“SchemaRegistryClient”反序列化 Python 中的 AVRO 消息

[英]Using 'SchemaRegistryClient' to deserialize AVRO message in Python

我们正在尝试使用来自其他系统的 AVRO 消息。 当我使用以下代码将架构指定为文件 (.avsc) 时,我能够读取 AVRO 消息,

import avro.schema
from avro.io import DatumReader, BinaryDecoder
...
schema = avro.schema.Parse(open("schema.avsc", "rb").read())
...
bytes_reader = io.BytesIO(element) # element is the serialized message
decoder = BinaryDecoder(bytes_reader)
reader = DatumReader(schema)
rec = reader.read(decoder)

但是,我现在需要从模式注册表 URL 中读取模式,

http://<IP>:<PORT>/subjects/<SUBJECT>/versions/<VERSION>/schema

我正在从传入消息自定义属性“模式”中提取 url。 现在要从 url 中获取模式,我使用以下代码,

def fetch_schema(IP, subject, version):
    sr = SchemaRegistryClient(IP)
    schema = sr.get_schema(subject, version=version).schema
    return schema

使用上面用于反序列化消息的相同代码,我现在收到以下错误

AttributeError: 'AvroSchema' object has no attribute 'type' 

在线上,

rec = reader.read(decoder) 

我比较了从文件读取时的“模式”变量的类型与从 URL 获取时的类型,

from file, the schema type is : <class 'avro.schema.RecordSchema'>
from URL, the schema type is : <class 'schema_registry.client.schema.AvroSchema'>

它们是不同的,因此可能是问题所在。 在这里寻找一些方向。 谢谢!

看来您需要从 Schema Registry API 调用中获取 JSON 表示,然后您可以像以前一样使用avro.schema.Parse

话虽如此,您可以只使用 urllib 或 requests,并且不需要SchemaRegistryClient

今天我从avro.schema.RecordSchema转换为schema_registry.client.schema.AvroSchema时遇到了同样的问题。 一种可能的解决方案是转储到JSON ,然后使用Avro库对其进行解析。

import avro.schema
from schema_registry.client import SchemaRegistryClient

client = SchemaRegistryClient(url="localhost:8081")
test_table_schema = client.get_schema("table_0_schema").schema

avro_schema = avro.schema.parse(json.dumps(test_table_schema.schema.raw_schema))

reader = DatumReader(avro_schema)

警告:

在使用KafkaAvro时,还可能发生其他一些问题:

  • 刷新非 avro 消息的主题。 由于 Kafka 消费者具有auto_offset_reset='earliest'设置,我从使用 json 格式推送的Avro消息中损失了很多时间。
  • 在使用DebeziumConfluent版本时,可能有 5 个字节专用于模式 ID。 您的解码 function 应如下所示:
def decode(msg_value):
    message_bytes = io.BytesIO(msg_value)
    message_bytes.seek(5) # <-----
    decoder = BinaryDecoder(message_bytes)
    event_dict = reader.read(decoder)
    return event_dict

检查答案以获取更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM