|
18 | 18 | import decimal
|
19 | 19 | import re
|
20 | 20 | from collections import defaultdict
|
| 21 | +from copy import deepcopy |
21 | 22 | from io import BytesIO
|
22 | 23 | from json import loads
|
23 | 24 | from struct import pack, unpack
|
24 | 25 | from typing import Dict, Union, Optional, Set, Callable
|
25 | 26 |
|
26 |
| -from fastavro import (parse_schema, |
27 |
| - schemaless_reader, |
| 27 | +from fastavro import (schemaless_reader, |
28 | 28 | schemaless_writer,
|
| 29 | + repository, |
29 | 30 | validate)
|
| 31 | +from fastavro.schema import load_schema |
30 | 32 |
|
31 | 33 | from . import (_MAGIC_BYTE,
|
32 | 34 | Schema,
|
@@ -104,7 +106,8 @@ def _resolve_named_schema(
|
104 | 106 | for ref in schema.references:
|
105 | 107 | referenced_schema = schema_registry_client.get_version(ref.subject, ref.version, True)
|
106 | 108 | ref_named_schemas = _resolve_named_schema(referenced_schema.schema, schema_registry_client)
|
107 |
| - parsed_schema = parse_schema(loads(referenced_schema.schema.schema_str), named_schemas=ref_named_schemas) |
| 109 | + parsed_schema = parse_schema_with_repo( |
| 110 | + referenced_schema.schema.schema_str, named_schemas=ref_named_schemas) |
108 | 111 | named_schemas.update(ref_named_schemas)
|
109 | 112 | named_schemas[ref.name] = parsed_schema
|
110 | 113 | return named_schemas
|
@@ -378,8 +381,8 @@ def _get_parsed_schema(self, schema: Schema) -> AvroSchema:
|
378 | 381 |
|
379 | 382 | named_schemas = _resolve_named_schema(schema, self._registry)
|
380 | 383 | prepared_schema = _schema_loads(schema.schema_str)
|
381 |
| - parsed_schema = parse_schema( |
382 |
| - loads(prepared_schema.schema_str), named_schemas=named_schemas, expand=True) |
| 384 | + parsed_schema = parse_schema_with_repo( |
| 385 | + prepared_schema.schema_str, named_schemas=named_schemas) |
383 | 386 |
|
384 | 387 | self._parsed_schemas.set(schema, parsed_schema)
|
385 | 388 | return parsed_schema
|
@@ -606,13 +609,28 @@ def _get_parsed_schema(self, schema: Schema) -> AvroSchema:
|
606 | 609 |
|
607 | 610 | named_schemas = _resolve_named_schema(schema, self._registry)
|
608 | 611 | prepared_schema = _schema_loads(schema.schema_str)
|
609 |
| - parsed_schema = parse_schema( |
610 |
| - loads(prepared_schema.schema_str), named_schemas=named_schemas, expand=True) |
| 612 | + parsed_schema = parse_schema_with_repo( |
| 613 | + prepared_schema.schema_str, named_schemas=named_schemas) |
611 | 614 |
|
612 | 615 | self._parsed_schemas.set(schema, parsed_schema)
|
613 | 616 | return parsed_schema
|
614 | 617 |
|
615 | 618 |
|
| 619 | +class LocalSchemaRepository(repository.AbstractSchemaRepository): |
| 620 | + def __init__(self, schemas): |
| 621 | + self.schemas = schemas |
| 622 | + |
| 623 | + def load(self, subject): |
| 624 | + return self.schemas.get(subject) |
| 625 | + |
| 626 | + |
| 627 | +def parse_schema_with_repo(schema_str: str, named_schemas: Dict[str, AvroSchema]) -> AvroSchema: |
| 628 | + copy = deepcopy(named_schemas) |
| 629 | + copy["$root"] = loads(schema_str) |
| 630 | + repo = LocalSchemaRepository(copy) |
| 631 | + return load_schema("$root", repo=repo) |
| 632 | + |
| 633 | + |
616 | 634 | def transform(
|
617 | 635 | ctx: RuleContext, schema: AvroSchema, message: AvroMessage,
|
618 | 636 | field_transform: FieldTransform
|
|
0 commit comments