对于瓶装水pg,Python消费者如何读取数据?

对于瓶装水pg,Python消费者如何读取数据?,python,avro,apache-kafka,Python,Avro,Apache Kafka,我用Python编写了一个消费者,如下所示: from kafka import KafkaConsumer import avro.schema import avro.io import io # To consume messages consumer = KafkaConsumer('test', group_id='', bootstrap_servers=['kafka:9092']

我用Python编写了一个消费者,如下所示:

from kafka import KafkaConsumer
import avro.schema
import avro.io
import io

# To consume messages
consumer = KafkaConsumer('test',
                         group_id='',
                         bootstrap_servers=['kafka:9092'])


schema = """
{
    "namespace":"com.martinkl.bottledwater.dbschema.public",
    "type":"record",
    "name":"test",
    "fields":[
        {"name":"id","type":["int", "null"]},
        {"name":"value","type":["string", "null"]}
    ]
}
"""
schema = avro.schema.parse(schema)

for msg in consumer:
    bytes_reader = io.BytesIO(msg.value)
    decoder = avro.io.BinaryDecoder(bytes_reader)
    reader = avro.io.DatumReader(schema)
    hello = reader.read(decoder)
    print hello
看起来一切正常,但当我运行insert data to Postgres时:

postgres=# insert into test (value) values('hello world!');
消费者的输出为空:

$ python consumer_bottledwater-pg.py 
{u'id': 0, u'value': u''}

请帮我把它修好。提前感谢。

瓶装水发布给卡夫卡的Avro编码信息以5字节的头作为前缀。第一个字节始终为零(保留供将来使用),接下来的4个字节是一个大端32位数字,指示模式的ID

在您的示例中,您已经在Python应用程序中硬编码了模式,但是一旦上游数据库模式发生变化,这种方法就会崩溃。这就是为什么瓶装水最好与饮用水一起使用。当您阅读来自Kafka的消息时,您首先解码标题以查找模式ID,如果您以前没有看到该模式ID,则需要查找模式。然后可以使用该模式解码消息的其余部分。模式可以缓存在使用者中,因为注册表保证特定ID的模式是不可变的


您还可以查看模式注册表附带的代码,以了解如何在Java中进行解码。在Python中也可以这样做。

非常感谢@Martin Kleppmann。我按照你的指示做了。它工作正常

value = bytearray(msg.value)
bytes_reader = io.BytesIO(value[5:])
decoder = avro.io.BinaryDecoder(bytes_reader)
reader = avro.io.DatumReader(schema)
hello = reader.read(decoder)
print hello

查看

的详细信息,非常感谢您的快速回答和建议。
KafkaMessage(topic='test',partition=0,offset=127,key='\x00\x00\x00\x00\x01\x02\x08\x01',value='\x00\x00\x02\x02\x08\x01\x02\x18 Hello world!')
因此,如果我需要解码Avro数据,我必须删除“value”中的5字节头吗?@NguyenSyThanhSon是的。前5个字节
\x00\x00\x00\x00\x02
表示它是架构ID 2。只要看看我链接到的Java代码,它就向您展示了如何对其进行解码。