【问题标题】:Python Avro avro.io.AvroTypeException The datum is not an example of schemaPython Avro avro.io.AvroTypeException 数据不是模式的示例
【发布时间】:2021-10-14 19:39:11
【问题描述】:

在问这个问题之前我搜索了很多,看起来我被卡住了,因此在这里问问题。我知道当 Schema 和 object 不匹配时会遇到此类错误,可能缺少某些数据类型或字段具有其他类型的值。

但是,我相信我的情况有所不同。 我的应用程序很简单,它只将一个对象序列化和反序列化为 avro

我的数据类:


from time import time
from faker import Faker
from dataclasses import dataclass, field

from dataclasses_avroschema import AvroModel

Faker.seed(0)
fake = Faker()


@dataclass
class Head(AvroModel):
    msgId: str = field()
    msgCode: str = field()

    @staticmethod
    def fakeMe():
        return Head(fake.md5(),
                fake.pystr(min_chars=5, max_chars=5)
            )


@dataclass
class Message(AvroModel):
    head: Head = field()
    status: bool = field()

    class Meta:
        namespace = "me.com.Message.v1"

    def fakeMe(self):
        self.head = Head.fakeMe()
        self.bool = fake.pybool()


现在是运行序列化的脚本:

import json, io as mainio
from dto.temp_schema import Message
from avro import schema, datafile, io as avroio

obj = Message(None, True)
obj.fakeMe()

schema_obj = schema.parse(json.dumps(Message.avro_schema_to_python()))

buf = mainio.BytesIO()
writer = datafile.DataFileWriter(buf, avroio.DatumWriter(), schema_obj)
writer.append(obj)
writer.flush()
buf.seek(0)
data = buf.read()

print("serialized avro: ", data)

当我运行它时,我得到以下错误:


Traceback (most recent call last):
  File "/Users/office/Documents/projects/msg-bench/scrib.py", line 28, in <module>
    writer.append(obj)
  File "/Users/office/opt/anaconda3/envs/benchenv/lib/python3.9/site-packages/avro/datafile.py", line 329, in append
    self.datum_writer.write(datum, self.buffer_encoder)
  File "/Users/office/opt/anaconda3/envs/benchenv/lib/python3.9/site-packages/avro/io.py", line 771, in write
    raise AvroTypeException(self.writer_schema, datum)


avro.io.AvroTypeException: The datum Message(head=Head(msgId='f112d652ecf13dacd9c78c11e1e7f987', msgCode='cYzVR'), status=True) is not an example of the schema {
  "type": "record",
  "name": "Message",
  "namespace": "me.com.Message.v1",
  "fields": [
    {
      "type": {
        "type": "record",
        "name": "Head",
        "namespace": "me.com.Message.v1",
        "fields": [
          {
            "type": "string",
            "name": "msgId"
          },
          {
            "type": "string",
            "name": "msgCode"
          }
        ],
        "doc": "Head(msgId: str, msgCode: str)"
      },
      "name": "head"
    },
    {
      "type": "boolean",
      "name": "status"
    }
  ],
  "doc": "Message(head: dto.temp_schema.Head, status: bool)"
}


请注意,我在 python 库的帮助下使用 Dataclass Object 生成模式: dataclasses-avroschema

在使用相同的架构之后,我仍然无法将数据序列化到 Avro。

目前我不确定我哪里出错了,而且我是 avro 的新手。为什么这不会编译?

系统和库统计数据:


Python==3.9.7
avro==1.10.2
avro-python3==1.10.2
dataclasses-avroschema==0.25.1
Faker==9.3.1
fastavro==1.4.5


【问题讨论】:

    标签: python python-3.x serialization avro


    【解决方案1】:

    问题是您试图将 Message 对象传递给不期望这样的标准 avro 库(而是期望字典)。您正在使用的库有一节讨论序列化,您可能想看看:https://marcosschroh.github.io/dataclasses-avroschema/serialization/

    所以你的脚本只需要是这样的:

    from dto.temp_schema import Message
    
    obj = Message(None, True)
    obj.fakeMe()
    print("serialized avro: ", obj.serialize())
    

    【讨论】:

      猜你喜欢
      • 2016-06-13
      • 1970-01-01
      • 2020-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-16
      • 1970-01-01
      相关资源
      最近更新 更多