With bottledwater-pg, how to read data by a Python consumer?

时间:2015-06-25 10:02:22

标签: python avro apache-kafka

I wrote a consumer in Python as below:

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

Everything seems OK, but when i run insert data to Postgres:

postgres=# insert into test (value) values('hello world!');

The output of consumer is empty:

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

Please help me to fix it out. Thank you in advance.

2 个答案:

答案 0 :(得分:3)

Bottled Water发布给Kafka的Avro编码消息带有5个字节的标头。第一个字节始终为零(保留供将来使用),接下来的4个字节是一个32位的大端数字,表示模式的ID。

在您的示例中,您已经在Python应用程序中对模式进行了硬编码,但是一旦上游数据库模式发生更改,该方法就会崩溃。这就是为什么瓶装水最好与schema registry一起使用。当您从Kafka读取消息时,首先解码标头以查找架构ID,如果之前没有看到该架构ID,则query the registry找到架构。然后,您可以使用该架构解码消息的其余部分。模式可以缓存在使用者中,因为注册表保证特定ID的模式是不可变的。

您还可以查看架构注册表附带的KafkaAvroDeserializer的代码,以了解如何在Java中完成此解码。您可以在Python中执行相同的操作。

答案 1 :(得分:0)

非常感谢@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

请参阅python-kafka-avro

上的详细信息