Add support for Avro aliases
Aliases allow a writer field to have a different name than the reader
field.
This closes issue
MODIFY
fastavro/_read.pyx
fastavro/_read.pyx
@@ -454,11 +454,19 @@ cpdef read_record(ReaderBase fo, writer_schema, reader_schema=None):
for field in writer_schema['fields']:
record[field['name']] = _read_data(fo, field['type'])
else:
- readers_field_dict = {f['name']: f for f in reader_schema['fields']}
+ readers_field_dict = {}
+ aliases_field_dict = {}
+ for f in reader_schema['fields']:
+ readers_field_dict[f['name']] = f
+ for alias in f.get('aliases', []):
+ aliases_field_dict[alias] = f
+
for field in writer_schema['fields']:
readers_field = readers_field_dict.get(field['name'])
+ if not readers_field:
+ readers_field = aliases_field_dict.get(field['name'])
if readers_field:
- record[field['name']] = _read_data(fo,
+ record[readers_field['name']] = _read_data(fo,
field['type'],
readers_field['type'])
else:

MODIFY
tests/test_fastavro.py
tests/test_fastavro.py
@@ -601,6 +601,56 @@ def test_schema_migration_reader_union():
assert new_records == records
+def test_aliases_not_present():
+ schema = {
+ "type": "record",
+ "fields": [{
+ "name": "test",
+ "type": "double"
+ }]
+ }
+
+ new_schema = {
+ "type": "record",
+ "fields": [
+ {"name": "newtest", "type": "double", "aliases": ["testX"]},
+ ]
+ }
+
+ new_file = MemoryIO()
+ records = [{"test": 1.2}]
+ fastavro.writer(new_file, schema, records)
+ new_file.seek(0)
+ reader = fastavro.reader(new_file, new_schema)
+ with pytest.raises(fastavro.read.SchemaResolutionError):
+ list(reader)
+
+
+def test_incompatible_aliases():
+ schema = {
+ "type": "record",
+ "fields": [{
+ "name": "test",
+ "type": "double"
+ }]
+ }
+
+ new_schema = {
+ "type": "record",
+ "fields": [
+ {"name": "newtest", "type": "int", "aliases": ["test"]},
+ ]
+ }
+
+ new_file = MemoryIO()
+ records = [{"test": 1.2}]
+ fastavro.writer(new_file, schema, records)
+ new_file.seek(0)
+ reader = fastavro.reader(new_file, new_schema)
+ with pytest.raises(fastavro.read.SchemaResolutionError):
+ list(reader)
+
+
def test_schema_migration_union_failure():
schema = {
"type": "record",
@@ -739,6 +789,33 @@ def test_schema_migration_schema_mismatch():
list(new_reader)
+def test_aliases_in_reader_schema():
+ schema = {
+ "type": "record",
+ "fields": [{
+ "name": "test",
+ "type": "int"
+ }]
+ }
+
+ new_schema = {
+ "type": "record",
+ "fields": [{
+ "name": "newtest",
+ "type": "int",
+ "aliases": ["test"]
+ }]
+ }
+
+ new_file = MemoryIO()
+ records = [{"test": 1}]
+ fastavro.writer(new_file, schema, records)
+ new_file.seek(0)
+ new_reader = fastavro.reader(new_file, new_schema)
+ new_records = list(new_reader)
+ assert new_records[0]["newtest"] == records[0]["test"]
+
+
def test_empty():
io = MemoryIO()
schema = {

Add support for Avro aliases

Aliases allow a writer field to have a different name than the reader
field.

This closes issue #87.