Python3 apache avro 1.8.2 не предоставляет псевдонимы

У меня есть следующая программа avro python3:

import avro.schema
import json
from avro.datafile import DataFileReader, DataFileWriter
from avro.io import DatumReader, DatumWriter


write_schema = avro.schema.parse(json.dumps({
    "namespace": "example.avro",
    "type": "record",
    "name": "User",
    "fields": [
         {"name": "name", "type": "string"},
         {"name": "favorite_number", "type": ["int", "null"]},
         {"name": "favorite_color", "type": ["string", "null"]}
     ]
}))

writer = DataFileWriter(open("users.avro", "wb"), DatumWriter(), write_schema)
writer.append({"name": "Alyssa", "favorite_number": 256})
writer.append({"name": "Ben", "favorite_number": 7, "favorite_color": "red"})
writer.close()

read_schema = avro.schema.parse(json.dumps({
    "namespace": "example.avro",
    "type": "record",
    "name": "User",
    "fields": [
        {"name": "first_name", "type": "string", "default": "", "aliases": ["name"]},
        {"name": "favorite_number", "type": ["int", "null"]},
        {"name": "favorite_color", "type": ["string", "null"]}
    ]
}))

reader = DataFileReader(open("users.avro", "rb"), DatumReader(write_schema, read_schema))
new_schema = reader.get_meta("avro.schema")
users = []
for user in reader:
    users.append(user)
reader.close()

Содержание users следующее:

[{'favorite_color': None, 'favorite_number': 256, 'first_name': ''},
 {'favorite_color': 'red', 'favorite_number': 7, 'first_name': ''}]

Я бы подумал, что в поле first_name будут «Бен» и «Алисса». Как работают псевдонимы в этой библиотеке? Это соответствует спецификации?


person user2302244    schedule 08.01.2018    source источник


Ответы (2)


Это работает с использованием fastavro. Вот тот же фрагмент, использующий эту библиотеку:

from io import BytesIO
from fastavro import reader, writer

write_schema = {
    "namespace": "example.avro",
    "type": "record",
    "name": "User",
    "fields": [
         {"name": "name", "type": "string"},
         {"name": "favorite_number", "type": ["int", "null"]},
         {"name": "favorite_color", "type": ["string", "null"]}
     ]
}

records = [
    {"name": "Alyssa", "favorite_number": 256},
    {"name": "Ben", "favorite_number": 7, "favorite_color": "red"}
]

bio = BytesIO()
writer(bio, write_schema, records)

bio.seek(0)

read_schema = {
    "namespace": "example.avro",
    "type": "record",
    "name": "User",
    "fields": [
        {"name": "first_name", "type": "string", "default": "", "aliases": ["name"]},
        {"name": "favorite_number", "type": ["int", "null"]},
        {"name": "favorite_color", "type": ["string", "null"]}
    ]
}

for record in reader(bio, read_schema):
    print(record)

И вывод:

{'first_name': 'Alyssa', 'favorite_number': 256, 'favorite_color': None}
{'first_name': 'Ben', 'favorite_number': 7, 'favorite_color': 'red'}
person Scott    schedule 27.06.2018

К сожалению, теперь я обнаружил, что версия стандартного пакета avro для python не реализует псевдонимы (https://issues.apache.org/jira/browse/AVRO-1303). Поскольку это было примерно с 2013/2014, я не ожидаю стандартного исправления в ближайшее время. Более перспективным является проект fastavro, который работает над исправлением.

person user2302244    schedule 14.01.2018