diff --git a/dataclasses_avroschema/model_generator/lang/python/base.py b/dataclasses_avroschema/model_generator/lang/python/base.py index 1edfc2f2..0b949d82 100644 --- a/dataclasses_avroschema/model_generator/lang/python/base.py +++ b/dataclasses_avroschema/model_generator/lang/python/base.py @@ -453,13 +453,19 @@ def render_field(self, field: JsonDict, model_name: str, parent_field_name: str) type_hint = self.parse_logical_type(field=field) elif isinstance(avro_type, dict): type_hint = "" - children = [self.render_field(field=avro_type, model_name=model_name, parent_field_name=name)] + children = [ + self.render_field(field=avro_type, model_name=model_name, parent_field_name=name or parent_field_name) + ] elif isinstance(avro_type, list): type_hint, children = self.parse_union(field_types=avro_type, model_name=model_name, parent_field_name=name) elif avro_type == field_utils.ARRAY: - type_hint, children = self.parse_array(field=field, model_name=model_name, parent_field_name=name) + type_hint, children = self.parse_array( + field=field, model_name=model_name, parent_field_name=name or parent_field_name + ) elif avro_type == field_utils.MAP: - type_hint, children = self.parse_map(field=field, model_name=model_name, parent_field_name=name) + type_hint, children = self.parse_map( + field=field, model_name=model_name, parent_field_name=name or parent_field_name + ) elif avro_type == field_utils.ENUM: type_hint = self.parse_enum(field=field) # We must set the default Enums type level default to dataclasses.MISSING diff --git a/tests/model_generator/conftest.py b/tests/model_generator/conftest.py index 92842ae5..df189a62 100644 --- a/tests/model_generator/conftest.py +++ b/tests/model_generator/conftest.py @@ -473,7 +473,7 @@ def schema_one_to_one_relationship() -> JsonDict: @pytest.fixture -def schema_one_to_many_relationship_clashes_types() -> JsonDict: +def schema_one_to_many_relationship_array_clashes_types() -> JsonDict: return { "type": "record", "name": "Message", @@ -498,6 +498,66 @@ def schema_one_to_many_relationship_clashes_types() -> JsonDict: ], "default": None, }, + { + "name": "Sender", + "type": { + "type": "array", + "items": { + "type": "record", + "name": "Sender", + "fields": [ + {"name": "company", "type": "string"}, + {"name": "delivered", "type": {"type": "long", "logicalType": "timestamp-millis"}}, + ], + }, + }, + "default": [], + }, + ], + } + + +@pytest.fixture +def schema_one_to_many_relationship_map_clashes_types() -> JsonDict: + return { + "type": "record", + "name": "Message", + "fields": [ + {"name": "MessageBody", "type": "string"}, + { + "name": "MessageHeader", + "type": [ + "null", + { + "type": "map", + "name": "MessageHeader", + "values": { + "type": "record", + "name": "MessageHeader", + "fields": [ + {"name": "version", "type": "string"}, + {"name": "MessageType", "type": "string"}, + ], + }, + }, + ], + "default": None, + }, + { + "name": "Sender", + "type": { + "type": "map", + "values": { + "type": "record", + "name": "Sender", + "fields": [ + {"name": "company", "type": "string"}, + {"name": "delivered", "type": {"type": "long", "logicalType": "timestamp-millis"}}, + ], + }, + }, + "default": {}, + }, ], } diff --git a/tests/model_generator/test_model_generator.py b/tests/model_generator/test_model_generator.py index bbee1f19..6b13fd9d 100644 --- a/tests/model_generator/test_model_generator.py +++ b/tests/model_generator/test_model_generator.py @@ -469,12 +469,13 @@ class User(AvroModel): assert result.strip() == expected_result.strip() -def test_schema_one_to_many_relationship_clashes_types( - schema_one_to_many_relationship_clashes_types: types.JsonDict, +def test_schema_one_to_many_relationship_array_clashes_types( + schema_one_to_many_relationship_array_clashes_types: types.JsonDict, ) -> None: expected_result = """ from dataclasses_avroschema import AvroModel import dataclasses +import datetime import typing @@ -486,13 +487,59 @@ class MessageHeader(AvroModel): _MessageHeader = MessageHeader +@dataclasses.dataclass +class Sender(AvroModel): + company: str + delivered: datetime.datetime + +_Sender = Sender + + @dataclasses.dataclass class Message(AvroModel): MessageBody: str MessageHeader: typing.Optional[typing.List[_MessageHeader]] = None + Sender: typing.List[_Sender] = dataclasses.field(default_factory=list) +""" + model_generator = ModelGenerator() + result = model_generator.render(schema=schema_one_to_many_relationship_array_clashes_types) + assert result.strip() == expected_result.strip() + + +def test_schema_one_to_many_relationship_map_clashes_types( + schema_one_to_many_relationship_map_clashes_types: types.JsonDict, +) -> None: + expected_result = """ +from dataclasses_avroschema import AvroModel +import dataclasses +import datetime +import typing + + +@dataclasses.dataclass +class MessageHeader(AvroModel): + version: str + MessageType: str + +_MessageHeader = MessageHeader + + +@dataclasses.dataclass +class Sender(AvroModel): + company: str + delivered: datetime.datetime + +_Sender = Sender + + +@dataclasses.dataclass +class Message(AvroModel): + MessageBody: str + MessageHeader: typing.Optional[typing.Dict[str, _MessageHeader]] = None + Sender: typing.Dict[str, _Sender] = dataclasses.field(default_factory=dict) """ model_generator = ModelGenerator() - result = model_generator.render(schema=schema_one_to_many_relationship_clashes_types) + result = model_generator.render(schema=schema_one_to_many_relationship_map_clashes_types) assert result.strip() == expected_result.strip() diff --git a/tests/schemas/avro/clashes_types_schema.avsc b/tests/schemas/avro/clashes_types_array_schema.avsc similarity index 61% rename from tests/schemas/avro/clashes_types_schema.avsc rename to tests/schemas/avro/clashes_types_array_schema.avsc index 17aaef5a..e5c7dbf1 100644 --- a/tests/schemas/avro/clashes_types_schema.avsc +++ b/tests/schemas/avro/clashes_types_array_schema.avsc @@ -30,6 +30,22 @@ } ], "default": null + }, + { + "name": "Sender", + "type": { + "type": "array", + "name": "Sender", + "items": { + "type": "record", + "name": "Sender", + "fields": [ + {"name": "company", "type": "string"}, + {"name": "delivered", "type": {"type": "long", "logicalType": "timestamp-millis"}} + ] + } + }, + "default": [] } ] } \ No newline at end of file diff --git a/tests/schemas/avro/clashes_types_map_schema.avsc b/tests/schemas/avro/clashes_types_map_schema.avsc new file mode 100644 index 00000000..ad5280e5 --- /dev/null +++ b/tests/schemas/avro/clashes_types_map_schema.avsc @@ -0,0 +1,51 @@ +{ + "type": "record", + "name": "Message", + "fields": [ + { + "name": "MessageBody", + "type": "string" + }, + { + "name": "MessageHeader", + "type": [ + "null", + { + "type": "map", + "values": { + "type": "record", + "name": "MessageHeader", + "fields": [ + { + "name": "version", + "type": "string" + }, + { + "name": "MessageType", + "type": "string" + } + ] + }, + "name": "MessageHeader" + } + ], + "default": null + }, + { + "name": "Sender", + "type": { + "type": "array", + "name": "Sender", + "items": { + "type": "record", + "name": "Sender", + "fields": [ + {"name": "company", "type": "string"}, + {"name": "delivered", "type": {"type": "long", "logicalType": "timestamp-millis"}} + ] + } + }, + "default": [] + } + ] +} \ No newline at end of file