diff --git a/datacontract/export/odcs_v3_exporter.py b/datacontract/export/odcs_v3_exporter.py index 6a34af94..6520befe 100644 --- a/datacontract/export/odcs_v3_exporter.py +++ b/datacontract/export/odcs_v3_exporter.py @@ -218,7 +218,7 @@ def to_property(field_name: str, field: Field) -> dict: if field.description is not None: property["description"] = field.description if field.required is not None: - property["nullable"] = not field.required + property["required"] = field.required if field.unique is not None: property["unique"] = field.unique if field.classification is not None: diff --git a/datacontract/imports/odcs_v3_importer.py b/datacontract/imports/odcs_v3_importer.py index 226d9d0f..c6422432 100644 --- a/datacontract/imports/odcs_v3_importer.py +++ b/datacontract/imports/odcs_v3_importer.py @@ -1,5 +1,6 @@ import datetime import logging +import re from typing import Any, Dict, List from venv import logger @@ -134,7 +135,7 @@ def import_servers(odcs_contract: Dict[str, Any]) -> Dict[str, Server] | None: server.outputPortId = odcs_server.get("outputPortId") server.driver = odcs_server.get("driver") server.roles = import_server_roles(odcs_server.get("roles")) - + server.storageAccount = re.search(r"(?:@|://)([^.]+)\.",odcs_server.get("location"),re.IGNORECASE) if server.type == "azure" else None servers[server_name] = server return servers @@ -288,8 +289,27 @@ def import_fields( else None, tags=odcs_property.get("tags") if odcs_property.get("tags") is not None else None, quality=odcs_property.get("quality") if odcs_property.get("quality") is not None else [], + fields=import_fields(odcs_property.get("properties"), custom_type_mappings, server_type) + if odcs_property.get("properties") is not None else {}, config=import_field_config(odcs_property, server_type), + format=odcs_property.get("format") if odcs_property.get("format") is not None else None, ) + #mapped_type is array + if field.type == "array" and odcs_property.get("items") is not None : + #nested array object + if odcs_property.get("items").get("logicalType") == "object": + field.items= Field(type="object", + fields=import_fields(odcs_property.get("items").get("properties"), custom_type_mappings, server_type)) + #array of simple type + elif odcs_property.get("items").get("logicalType") is not None: + field.items= Field(type = odcs_property.get("items").get("logicalType")) + + # enum from quality validValues as enum + if field.type == "string": + for q in field.quality: + if hasattr(q,"validValues"): + field.enum = q.validValues + result[property_name] = field else: logger.info( diff --git a/tests/fixtures/odcs_v3/adventureworks.datacontract.yml b/tests/fixtures/odcs_v3/adventureworks.datacontract.yml index fbe37277..969d21a0 100644 --- a/tests/fixtures/odcs_v3/adventureworks.datacontract.yml +++ b/tests/fixtures/odcs_v3/adventureworks.datacontract.yml @@ -4407,3 +4407,67 @@ models: criticalDataElement: false partitioned: false physicalType: timestamp + StoreHolidayHours: + title: StoreHolidayHours + type: array + required: false + primaryKey: false + unique: false + items: + type: object + fields: + Date: + title: Date + type: date + primaryKey: false + examples: + - '2024-08-13' + config: + physicalType: string + Close: + title: Close + type: date + primaryKey: false + examples: + - 02:00 PM + config: + physicalType: string + Open: + title: Open + type: date + primaryKey: false + examples: + - 10:00 AM + config: + physicalType: string + config: + physicalType: array + extendedData: + title: extendedData + type: object + required: true + primaryKey: false + unique: false + fields: + pharmacyUUID: + title: pharmacyUUID + type: string + required: true + primaryKey: false + unique: true + examples: + - ec43dd63-c258-4506-8965-88a9e0c130ad + config: + physicalType: string + config: + physicalType: object + ArrayComments: + title: ArrayComments + type: array + required: false + primaryKey: false + unique: false + items: + type: string + config: + physicalType: array \ No newline at end of file diff --git a/tests/fixtures/odcs_v3/adventureworks.odcs.yaml b/tests/fixtures/odcs_v3/adventureworks.odcs.yaml index c5e2a42d..b1fed2cb 100644 --- a/tests/fixtures/odcs_v3/adventureworks.odcs.yaml +++ b/tests/fixtures/odcs_v3/adventureworks.odcs.yaml @@ -5320,4 +5320,54 @@ schema: criticalDataElement: false primaryKey: false required: false + - name: StoreHolidayHours + businessName: StoreHolidayHours + logicalType: array + physicalType: array + required: false + unique: false + items: + logicalType: object + properties: + - name: Date + businessName: Date + logicalType: date + physicalType: string + examples: + - "2024-08-13" + - name: Close + businessName: Close + logicalType: date + physicalType: string + examples: + - "02:00 PM" + - name: Open + businessName: Open + logicalType: date + physicalType: string + examples: + - "10:00 AM" + - name: extendedData + businessName: extendedData + logicalType: object + physicalType: object + required: true + unique: false + properties: + - name : pharmacyUUID + businessName: pharmacyUUID + logicalType: string + physicalType: string + required: true + unique: true + examples: + - "ec43dd63-c258-4506-8965-88a9e0c130ad" + - name: ArrayComments + businessName: ArrayComments + logicalType: array + physicalType: array + required: false + unique: false + items: + logicalType: string contractCreatedTs: "2023-09-28T20:24:49.331+00:00" diff --git a/tests/test_export_odcs_v3.py b/tests/test_export_odcs_v3.py index ee922aee..c82d2a93 100644 --- a/tests/test_export_odcs_v3.py +++ b/tests/test_export_odcs_v3.py @@ -46,7 +46,7 @@ def test_to_odcs(): maxLength: 10 pattern: ^B[0-9]+$ physicalType: varchar - nullable: false + required: true unique: true tags: - "order_id" @@ -65,7 +65,7 @@ def test_to_odcs(): minimum: 0 maximum: 1000000 physicalType: bigint - nullable: false + required: true description: The order_total field quality: - type: sql @@ -77,7 +77,7 @@ def test_to_odcs(): - name: order_status logicalType: string physicalType: text - nullable: false + required: true quality: - type: sql description: Row Count