From f4d8d260d306fa67d32ebde1e557fb6d61392fff Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Thu, 2 May 2024 10:46:43 -0400 Subject: [PATCH 01/93] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2bd3b7c..fb14f1e 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ Welcome! Thanks for your interest and for taking the time to come here! ❤️ ## Executive summary -This standard describes a structure for a **data contract**. Its current version is 2.2.1. It is available for you as an Apache 2.0 license. Contributions are welcome! +This standard describes a structure for a **data contract**. Its current version is 3.0.0-dev. It is available for you as an Apache 2.0 license. Contributions are welcome! ## Discover the open standard -Discover the [Open Data Contract Standard](./docs/README.md). This file contains some explanations and several examples. More [examples](./examples/README.md) have been added to v2.2.1. +Discover the [Open Data Contract Standard](./docs/README.md). This file contains some explanations and several examples. More [examples](./examples/README.md) have been added to vTBD. ## What is a Data Contract? From addb24a74354022997ae863ee27060850637d9f3 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Thu, 30 May 2024 10:25:15 +0800 Subject: [PATCH 02/93] Add in date logical type --- .gitignore | 1 + docs/examples/data-types/all-data-types.yaml | 63 ++++++ docs/standard.md | 36 +++- schema/odcs-json-schema.json | 198 ++++++++++++++++++- 4 files changed, 292 insertions(+), 6 deletions(-) create mode 100644 docs/examples/data-types/all-data-types.yaml diff --git a/.gitignore b/.gitignore index ee59e97..fb778ee 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .DS_Store .idea site +*.iml diff --git a/docs/examples/data-types/all-data-types.yaml b/docs/examples/data-types/all-data-types.yaml new file mode 100644 index 0000000..f4529b1 --- /dev/null +++ b/docs/examples/data-types/all-data-types.yaml @@ -0,0 +1,63 @@ +version: 1.0.0 +kind: DataContract +uuid: 53581432-6c55-4ba2-a65f-72344a91553a +type: tables +status: current +datasetName: my_table +quantumName: my_quantum +dataset: + - table: transactions_tbl + description: Provides core payment metrics + dataGranularity: Aggregation on columns txn_ref_dt, pmt_txn_id + columns: + - column: account_id + physicalType: string + logicalType: string + logicalTypeOptions: + minLength: 11 + maxLength: 11 + pattern: ACC[0-9]{8} + - column: txn_ref_date + physicalType: date + logicalType: date + logicalTypeOptions: + minLength: 10 + maxLength: 10 + format: yyyy-MM-dd + - column: txn_timestamp + physicalType: timestamp + logicalType: date + logicalTypeOptions: + minLength: 19 + maxLength: 19 + format: "yyyy-MM-dd HH:mm:ss" + - column: amount + physicalType: double + logicalType: number + logicalTypeOptions: + minimum: 0 + - column: age + physicalType: int + logicalType: integer + logicalTypeOptions: + minimum: 18 + maximum: 100 + exclusiveMaximum: true + - column: is_open + physicalType: bool + logicalType: boolean + - column: latest_txns + physicalType: list + logicalType: array + logicalTypeOptions: + minItems: 0 + maxItems: 3 + uniqueItems: true + - column: customer_details + physicalType: json + logicalType: object + logicalTypeOptions: + required: + - num_children + - date_of_birth + maxProperties: 5 diff --git a/docs/standard.md b/docs/standard.md index da1a24c..0b566a3 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -206,8 +206,9 @@ dataset: | dataset.table.columns.column.isPrimaryKey | Primary Key | No | Boolean value specifying whether the column is primary or not. Default is false. | | dataset.table.columns.column.primaryKeyPosition | Primary Key Position | No | If column is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1. | | dataset.table.columns.column.businessName | Business Name | No | The business name of the column. | -| dataset.table.columns.column.logicalType | Logical Type | Yes | The logical column datatype. | -| dataset.table.columns.column.physicalType | Physical Type | Yes | The physical column datatype. | +| dataset.table.columns.column.logicalType | Logical Type | Yes | The logical column datatype. One of `string`, `date`, `number`, `integer`, `object`, `array` or `boolean`. | +| dataset.table.columns.column.logicalTypeOptions | Logical Type Options | No | Additional optional metadata to describe the logical type. See [here](#logical-type-options) for more details about supported options for each `logicalType`. | +| dataset.table.columns.column.physicalType | Physical Type | Yes | The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT. | | dataset.table.columns.column.description | Description | No | Description of the column. | | dataset.table.columns.column.isNullable | Nullable | No | Indicates if the column may contain Null values; possible values are true and false. Default is false. | | dataset.table.columns.column.isUnique | Unique | No | Indicates if the column contains unique values; possible values are true and false. Default is false. | @@ -224,9 +225,36 @@ dataset: | dataset.table.columns.column.sampleValues | Sample Values | No | List of sample column values. | | dataset.table.columns.column.criticalDataElementStatus | Critical Data Element Status | No | True or false indicator; If element is considered a critical data element (CDE) then true else false. | | dataset.table.columns.column.tags | Tags | No | A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level. | - | -### Authorative definitions + +### Logical Type Options + +Additional metadata options to more accurately define the data type. + +| Data Type | Key | UX Label | Required | Description | +|----------------|------------------|--------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| array | maxItems | Maximum Items | No | Maximum number of items. | +| array | minItems | Minimum Items | No | Minimum number of items. | +| array | uniqueItems | Unique Items | No | If set to true, all items in the array are unique. | +| date | format | Format | No | Format of the date. Follows the format as prescribed by [JDK DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). For example, format 'yyyy-MM-dd'. | +| date | exclusiveMaximum | Exclusive Maximum | No | If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum). | +| date | exclusiveMinimum | Exclusive Minimum | No | If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum). | +| date | maximum | Maximum | No | All date values are less than or equal to this value (values <= maximum). | +| date | minimum | Minimum | No | All date values are greater than or equal to this value (values >= minimum). | +| integer/number | exclusiveMaximum | Exclusive Maximum | No | If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum). | +| integer/number | exclusiveMinimum | Exclusive Minimum | No | If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum). | +| integer/number | maximum | Maximum | No | All values are less than or equal to this value (values <= maximum). | +| integer/number | minimum | Minimum | No | All values are greater than or equal to this value (values >= minimum). | +| integer/number | multipleOf | Multiple Of | No | Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5. | +| object | maxProperties | Maximum Properties | No | Maximum number of properties. | +| object | minProperties | Minimum Properties | No | Minimum number of properties. | +| object | required | Required | No | Property names that are required to exist in the object. | +| string | format | Format | No | Provides extra context about what format the string follows. For example, password, byte, binary, email, uuid, uri, hostname, ipv4, ipv6. | +| string | maxLength | Maximum Length | No | Maximum length of the string. | +| string | minLength | Minimum Length | No | Minimum length of the string. | +| string | pattern | Pattern | No | Regular expression pattern to define valid value. Follows regular expression syntax from ECMA-262 (https://262.ecma-international.org/5.1/#sec-15.10.1). | + +### Authoritative definitions Updated in ODCS (Open Data Contract Standard) v2.2.1. diff --git a/schema/odcs-json-schema.json b/schema/odcs-json-schema.json index b72086c..ad8e5c6 100644 --- a/schema/odcs-json-schema.json +++ b/schema/odcs-json-schema.json @@ -239,11 +239,205 @@ }, "logicalType": { "type": "string", - "description": "The logical column datatype." + "description": "The logical column data type.", + "enum": ["string", "date", "number", "integer", "object", "array", "boolean"] + }, + "logicalTypeOptions": { + "type": "object", + "description": "Additional optional metadata to describe the logical type.", + "properties": { + "enum": { + "type": "array", + "items": { + }, + "minItems": 1, + "uniqueItems": false, + "description": "Set of possible values." + } + }, + "allOf": [ + { + "if": { + "properties": { + "logicalType": { + "const": "string" + } + } + }, + "then": { + "properties": { + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length of the string." + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length of the string." + }, + "pattern": { + "type": "string", + "format": "regex", + "description": "Regular expression pattern to define valid value. Follows regular expression syntax from ECMA-262 (https://262.ecma-international.org/5.1/#sec-15.10.1)." + }, + "format": { + "type": "string", + "examples": ["password", "byte", "binary", "email", "uuid", "uri", "hostname", "ipv4", "ipv6"], + "description": "Provides extra context about what format the string follows." + } + } + } + },{ + "if": { + "properties": { + "logicalType": { + "const": "date" + } + } + }, + "then": { + "properties": { + "format": { + "type": "string", + "examples": ["yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "HH:mm:ss"], + "description": "Format of the date. Follows the format as prescribed by [JDK DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). For example, format 'yyyy-MM-dd'." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "maximum": { + "type": "string", + "description": "All date values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "minimum": { + "type": "string", + "description": "All date values are greater than or equal to this value (values >= minimum)." + } + } + } + }, + { + "if": { + "anyOf": [ + { + "properties": { + "logicalType": { + "const": "number" + } + } + }, + { + "properties": { + "logicalType": { + "const": "integer" + } + } + } + ] + }, + "then": { + "properties": { + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0, + "description": "Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5." + }, + "maximum": { + "type": "number", + "description": "All values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "minimum": { + "type": "number", + "description": "All values are greater than or equal to this value (values >= minimum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + } + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "object" + } + } + }, + "then": { + "properties": { + "maxProperties": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of properties." + }, + "minProperties": { + "type": "integer", + "minimum": 0, + "default": 0, + "description": "Minimum number of properties." + }, + "required": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "uniqueItems": true, + "description": "Property names that are required to exist in the object." + } + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "array" + } + } + }, + "then": { + "properties": { + "maxItems": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of items." + }, + "minItems": { + "type": "integer", + "minimum": 0, + "default": 0, + "description": "Minimum number of items" + }, + "uniqueItems": { + "type": "boolean", + "default": false, + "description": "If set to true, all items in the array are unique." + } + } + } + } + ] }, "physicalType": { "type": "string", - "description": "The physical column datatype." + "description": "The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT." }, "description": { "type": "string", From 21ab2d1085ad74a72ea5b8b1b99cb45d38177ed2 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Fri, 12 Jul 2024 22:32:22 +0800 Subject: [PATCH 03/93] Add in integer/number format to follow Rust integer format, add in v3.0.0 JSON schema, update latest schema, add in entry to changelog --- CHANGELOG.md | 8 + ...ta-types.yaml => all-data-types.odcs.yaml} | 9 +- docs/examples/index.md | 1 + docs/standard.md | 1 + schema/README.md | 2 +- schema/odcs-json-schema-latest.json | 339 ++++---- schema/odcs-json-schema-v3.0.0.json | 749 ++++++++++++++++++ 7 files changed, 945 insertions(+), 164 deletions(-) rename docs/examples/data-types/{all-data-types.yaml => all-data-types.odcs.yaml} (90%) create mode 100644 schema/odcs-json-schema-v3.0.0.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 83a3485..f4fde09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color This document tracks the history and evolution of the **Open Data Contract Standard**. +# v3.0.0 - 2024-07-12 - PROPOSED + +* In JSON schema: + * Restrict `dataset.table.columns.column.logicalType` to be one of `string, date, number, integer, object, array, boolean` + * Add `dataset.table.columns.column.logicalTypeOptions` +* Add [all data types example](docs/examples/data-types/all-data-types.odcs.yaml) +* Add [logical type options to standard](docs/standard.md#logical-type-options) + # v2.2.2 - 2024-05-23 - APPROVED * In JSON schema validation: diff --git a/docs/examples/data-types/all-data-types.yaml b/docs/examples/data-types/all-data-types.odcs.yaml similarity index 90% rename from docs/examples/data-types/all-data-types.yaml rename to docs/examples/data-types/all-data-types.odcs.yaml index f4529b1..a8231f5 100644 --- a/docs/examples/data-types/all-data-types.yaml +++ b/docs/examples/data-types/all-data-types.odcs.yaml @@ -21,15 +21,15 @@ dataset: physicalType: date logicalType: date logicalTypeOptions: - minLength: 10 - maxLength: 10 + minimum: 2020-01-01 + maximum: 2021-01-01 format: yyyy-MM-dd - column: txn_timestamp physicalType: timestamp logicalType: date logicalTypeOptions: - minLength: 19 - maxLength: 19 + minimum: 2020-01-01 00:00:00 + maximum: 2021-01-01 00:00:00 format: "yyyy-MM-dd HH:mm:ss" - column: amount physicalType: double @@ -43,6 +43,7 @@ dataset: minimum: 18 maximum: 100 exclusiveMaximum: true + format: i64 - column: is_open physicalType: bool logicalType: boolean diff --git a/docs/examples/index.md b/docs/examples/index.md index 12fd420..d1dc313 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -27,6 +27,7 @@ This folder contains mainly excerpt of data contracts to illustrate specific sec - [Table with single column](schema/table-column.odcs.yaml) - [Table with columns and partitioning](schema/table-columns-with-partition.odcs.yaml) +- [Data types](data-types/all-data-types.odcs.yaml) ## Data quality diff --git a/docs/standard.md b/docs/standard.md index 33622d1..41252e8 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -249,6 +249,7 @@ Additional metadata options to more accurately define the data type. | date | minimum | Minimum | No | All date values are greater than or equal to this value (values >= minimum). | | integer/number | exclusiveMaximum | Exclusive Maximum | No | If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum). | | integer/number | exclusiveMinimum | Exclusive Minimum | No | If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum). | +| integer/number | format | Format | No | Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types). | | integer/number | maximum | Maximum | No | All values are less than or equal to this value (values <= maximum). | | integer/number | minimum | Minimum | No | All values are greater than or equal to this value (values >= minimum). | | integer/number | multipleOf | Multiple Of | No | Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5. | diff --git a/schema/README.md b/schema/README.md index 82fd56a..aa2fcc3 100644 --- a/schema/README.md +++ b/schema/README.md @@ -19,7 +19,7 @@ following section: ```json { - "name": "Open Data Contract Standard (ODCS))", + "name": "Open Data Contract Standard (ODCS)", ..., "versions": { "": "https://github.com/bitol-io/open-data-contract-standard/blob/main/schema/odcs-json-schema-.json", diff --git a/schema/odcs-json-schema-latest.json b/schema/odcs-json-schema-latest.json index ad8e5c6..83580f5 100644 --- a/schema/odcs-json-schema-latest.json +++ b/schema/odcs-json-schema-latest.json @@ -16,8 +16,8 @@ }, "apiVersion": { "type": "string", - "default": "v2.2.2", - "description": "Version of the standard used to build data contract. Default value is v2.2.2.", + "default": "v3.0.0", + "description": "Version of the standard used to build data contract. Default value is v3.0.0.", "pattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+" }, "uuid": { @@ -244,27 +244,105 @@ }, "logicalTypeOptions": { "type": "object", - "description": "Additional optional metadata to describe the logical type.", - "properties": { - "enum": { - "type": "array", - "items": { - }, - "minItems": 1, - "uniqueItems": false, - "description": "Set of possible values." + "description": "Additional optional metadata to describe the logical type." + }, + "physicalType": { + "type": "string", + "description": "The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT." + }, + "description": { + "type": "string", + "description": "Description of the column." + }, + "isNullable": { + "type": "boolean", + "default": false, + "description": "Indicates if the column may contain Null values; possible values are true and false. Default is false." + }, + "isUnique": { + "type": "boolean", + "default": false, + "description": "Indicates if the column contains unique values; possible values are true and false. Default is false." + }, + "partitionStatus": { + "type": "boolean", + "default": false, + "description": "Indicates if the column is partitioned; possible values are true and false." + }, + "partitionKeyPosition": { + "type": "integer", + "default": -1, + "description": "If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1." + }, + "clusterStatus": { + "type": "boolean", + "default": false, + "description": "Indicates of the column is clustered; possible values are true and false." + }, + "clusterKeyPosition": { + "type": "integer", + "default": -1, + "description": "If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1." + }, + "classification": { + "type": "string", + "description": "Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5.", + "examples": ["confidential", "restricted", "public"] + }, + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "encryptedColumnName": { + "type": "string", + "description": "The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`." + }, + "transformSourceTables": { + "type": "array", + "description": "List of sources used in column transformation.", + "items": { + "type": "string" + } + }, + "transformLogic": { + "type": "string", + "description": "Logic used in the column transformation." + }, + "transformDescription": { + "type": "string", + "description": "Describes the transform logic in very simple terms." + }, + "sampleValues": { + "type": "array", + "description": "List of sample column values.", + "items": { + "type": "string" + } + }, + "criticalDataElementStatus": { + "type": "boolean", + "default": false, + "description": "True or false indicator; If element is considered a critical data element (CDE) then true else false." + }, + "tags": { + "type": "array", + "description": "A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level.", + "items": { + "type": "string" + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "logicalType": { + "const": "string" + } } }, - "allOf": [ - { - "if": { - "properties": { - "logicalType": { - "const": "string" - } - } - }, - "then": { + "then": { + "properties": { + "logicalTypeOptions": { "properties": { "minLength": { "type": "integer", @@ -286,17 +364,22 @@ "examples": ["password", "byte", "binary", "email", "uuid", "uri", "hostname", "ipv4", "ipv6"], "description": "Provides extra context about what format the string follows." } - } + }, + "additionalProperties": false } - },{ - "if": { - "properties": { - "logicalType": { - "const": "date" - } - } - }, - "then": { + } + } + }, { + "if": { + "properties": { + "logicalType": { + "const": "date" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { "properties": { "format": { "type": "string", @@ -321,29 +404,34 @@ "type": "string", "description": "All date values are greater than or equal to this value (values >= minimum)." } - } + }, + "additionalProperties": false } - }, - { - "if": { - "anyOf": [ - { - "properties": { - "logicalType": { - "const": "number" - } - } - }, - { - "properties": { - "logicalType": { - "const": "integer" - } - } + } + } + }, + { + "if": { + "anyOf": [ + { + "properties": { + "logicalType": { + "const": "number" } - ] + } }, - "then": { + { + "properties": { + "logicalType": { + "const": "integer" + } + } + } + ] + }, + "then": { + "properties": { + "logicalTypeOptions": { "properties": { "multipleOf": { "type": "number", @@ -367,19 +455,30 @@ "type": "boolean", "default": false, "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "format": { + "type": "string", + "default": "i32", + "description": "Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types).", + "enum": ["i8", "i16", "i32", "i64", "i128", "u8", "u16", "u32", "u64", "u128"] } - } + }, + "additionalProperties": false } - }, - { - "if": { - "properties": { - "logicalType": { - "const": "object" - } - } - }, - "then": { + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "object" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { "properties": { "maxProperties": { "type": "integer", @@ -401,18 +500,23 @@ "uniqueItems": true, "description": "Property names that are required to exist in the object." } - } + }, + "additionalProperties": false } - }, - { - "if": { - "properties": { - "logicalType": { - "const": "array" - } - } - }, - "then": { + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "array" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { "properties": { "maxItems": { "type": "integer", @@ -430,96 +534,13 @@ "default": false, "description": "If set to true, all items in the array are unique." } - } + }, + "additionalProperties": false } } - ] - }, - "physicalType": { - "type": "string", - "description": "The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT." - }, - "description": { - "type": "string", - "description": "Description of the column." - }, - "isNullable": { - "type": "boolean", - "default": false, - "description": "Indicates if the column may contain Null values; possible values are true and false. Default is false." - }, - "isUnique": { - "type": "boolean", - "default": false, - "description": "Indicates if the column contains unique values; possible values are true and false. Default is false." - }, - "partitionStatus": { - "type": "boolean", - "default": false, - "description": "Indicates if the column is partitioned; possible values are true and false." - }, - "partitionKeyPosition": { - "type": "integer", - "default": -1, - "description": "If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1." - }, - "clusterStatus": { - "type": "boolean", - "default": false, - "description": "Indicates of the column is clustered; possible values are true and false." - }, - "clusterKeyPosition": { - "type": "integer", - "default": -1, - "description": "If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1." - }, - "classification": { - "type": "string", - "description": "Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5.", - "examples": ["confidential", "restricted", "public"] - }, - "authoritativeDefinitions": { - "$ref": "#/$defs/AuthoritativeDefinitions" - }, - "encryptedColumnName": { - "type": "string", - "description": "The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`." - }, - "transformSourceTables": { - "type": "array", - "description": "List of sources used in column transformation.", - "items": { - "type": "string" - } - }, - "transformLogic": { - "type": "string", - "description": "Logic used in the column transformation." - }, - "transformDescription": { - "type": "string", - "description": "Describes the transform logic in very simple terms." - }, - "sampleValues": { - "type": "array", - "description": "List of sample column values.", - "items": { - "type": "string" - } - }, - "criticalDataElementStatus": { - "type": "boolean", - "default": false, - "description": "True or false indicator; If element is considered a critical data element (CDE) then true else false." - }, - "tags": { - "type": "array", - "description": "A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level.", - "items": { - "type": "string" } } - }, + ], "required": ["column", "logicalType", "physicalType"] }, "DataQuality": { diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json new file mode 100644 index 0000000..83580f5 --- /dev/null +++ b/schema/odcs-json-schema-v3.0.0.json @@ -0,0 +1,749 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "Open Data Contract Standard (OCDS)", + "description": "An open data contract specification to establish agreement between data producers and consumers.", + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "Current version of the data contract." + }, + "kind": { + "type": "string", + "default": "DataContract", + "description": "The kind of file this is. Valid value is `DataContract`.", + "enum": ["DataContract"] + }, + "apiVersion": { + "type": "string", + "default": "v3.0.0", + "description": "Version of the standard used to build data contract. Default value is v3.0.0.", + "pattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+" + }, + "uuid": { + "type": "string", + "description": "A unique identifier used to reduce the risk of dataset name collisions; initially the UUID will be created using a UUID generator tool ([example](https://www.uuidgenerator.net/)). However, we may want to develop a method that accepts a seed value using a combination of fields–such as name, kind and source–to create a repeatable value." + }, + "datasetKind": { + "type": "string", + "description": "The kind of dataset being cataloged; Expected values are `virtualDataset` or `managedDataset`.", + "examples": ["virtualDataset", "managedDataset"] + }, + "userConsumptionMode": { + "type": "string", + "description": "List of data modes for which the dataset may be used. Expected sample values might be `analytical` or `operational`.
Note: in the future, this will probably be replaced by ports.", + "examples": ["analytical", "operational"] + }, + "type": { + "type": "string", + "description": "Identifies the types of objects in the dataset. For BigQuery or any other database, the expected value would be Tables.", + "examples": ["Tables"] + }, + "tenant": { + "type": "string", + "description": "Indicates the property the data is primarily associated with. Value is case insensitive." + }, + "tags": { + "type": "array", + "description": "A list of tags that may be assigned to the dataset, table or column; the `tags` keyword may appear at any level.", + "items": { + "type": "string" + } + }, + "status": { + "type": "string", + "description": "Current status of the dataset. Valid values are `production`, `test`, or `development`.", + "examples": ["production", "test", "development"] + }, + "sourceSystem": { + "type": "string", + "description": "The system where the dataset resides. Expected value can be BigQuery.", + "examples": ["BigQuery"] + }, + "sourcePlatform": { + "type": "string", + "description": "The platform where the dataset resides. Expected value is GoogleCloudPlatform, IBMCloud, Azure...", + "examples": ["GoogleCloudPlatform", "IBMCloud", "Azure", "AWS"] + }, + "server": { + "type": "string", + "description": "The server where the dataset resides." + }, + "quantumName": { + "type": "string", + "description": "The name of the data quantum or data product." + }, + "productSlackChannel": { + "type": "string", + "description": "Slack channel of the team responsible for maintaining the dataset." + }, + "productFeedbackUrl": { + "type": "string", + "description": "The URL for submitting feedback to the team responsible for maintaining the dataset." + }, + "productDl": { + "type": "string", + "description": "The email distribution list (DL) of the persons or team responsible for maintaining the dataset." + }, + "username": { + "type": "string", + "description": "User credentials for connecting to the dataset; how the credentials will be stored/passed is outside of the scope of the contract." + }, + "password": { + "type": "string", + "description": "User credentials for connecting to the dataset; how the credentials will be stored/passed is out of the scope of this contract." + }, + "driverVersion": { + "type": "string", + "description": "The version of the connection driver to be used to connect to the dataset." + }, + "driver": { + "type": "string", + "description": "The connection driver required to connect to the dataset." + }, + "description": { + "type": "object", + "description": "High level description of the dataset.", + "properties": { + "usage": { + "type": "string", + "description": "Intended usage of the dataset." + }, + "purpose": { + "type": "string", + "description": "Purpose of the dataset." + }, + "limitations": { + "type": "string", + "description": "Limitations of the dataset." + } + } + }, + "project": { + "type": "string", + "description": "Associated project name, can be used for billing or administrative purpose. Used to be datasetProject." + }, + "datasetName": { + "type": "string", + "description": "May be required in cloud instance like GCP BigQuery dataset name." + }, + "datasetDomain": { + "type": "string", + "description": "Name of the logical domain dataset the contract describes. This field is only required for output data contracts.", + "examples": ["imdb_ds_aggregate", "receiver_profile_out", "transaction_profile_out"] + }, + "database": { + "type": "string", + "description": "The database where the dataset resides." + }, + "dataset": { + "type": "array", + "items": { + "$ref": "#/$defs/Dataset" + } + }, + "price": { + "$ref": "#/$defs/Pricing" + }, + "stakeholders": { + "type": "array", + "items": { + "$ref": "#/$defs/Stakeholder" + } + }, + "roles": { + "type": "array", + "description": "A list of roles that will provide user access to the dataset.", + "items": { + "$ref": "#/$defs/Role" + } + }, + "slaDefaultColumn": { + "type": "string", + "description": "Columns (using the Table.Column notation) to do the checks on. By default, it is the partition column." + }, + "slaProperties": { + "type": "array", + "description": "A list of key/value pairs for SLA specific properties. There is no limit on the type of properties (more details to come).", + "items": { + "$ref": "#/$defs/ServiceLevelAgreementProperty" + } + } + }, + "required": ["version", "kind", "uuid", "type", "status", "dataset", "datasetName", "quantumName"], + "$defs": { + "Dataset": { + "type": "object", + "properties": { + "table": { + "type": "string", + "description": "Name of the table being cataloged; the value should only contain the table name. Do not include the project or dataset name in the value." + }, + "physicalName": { + "type": "string", + "description": "Physical name of the table, default value is table name + version separated by underscores, as `table_1_2_0`.", + "examples": ["table_1_2_0"] + }, + "priorTableName": { + "type": "string", + "description": "Name of the previous version of the dataset, if applicable." + }, + "description": { + "type": "string", + "description": "Description of the dataset." + }, + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "dataGranularity": { + "type": "string", + "description": "Granular level of the data in the table. Example would be `pmt_txn_id`.", + "examples": ["pmt_txn_id"] + }, + "columns": { + "type": "array", + "description": "Array. A list of columns in the table.", + "items": { + "$ref": "#/$defs/Column" + } + }, + "quality": { + "type": "array", + "description": "Data quality rules with all the relevant information for rule setup and execution.", + "items": { + "$ref": "#/$defs/DataQuality" + } + } + }, + "required": ["table"] + }, + "Column": { + "type": "object", + "properties": { + "column": { + "type": "string", + "description": "The name of the column." + }, + "isPrimaryKey": { + "type": "boolean", + "description": "Boolean value specifying whether the column is primary or not. Default is false." + }, + "primaryKeyPosition": { + "type": "integer", + "default": -1, + "description": "If column is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1." + }, + "businessName": { + "type": "string", + "description": "The business name of the column." + }, + "logicalType": { + "type": "string", + "description": "The logical column data type.", + "enum": ["string", "date", "number", "integer", "object", "array", "boolean"] + }, + "logicalTypeOptions": { + "type": "object", + "description": "Additional optional metadata to describe the logical type." + }, + "physicalType": { + "type": "string", + "description": "The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT." + }, + "description": { + "type": "string", + "description": "Description of the column." + }, + "isNullable": { + "type": "boolean", + "default": false, + "description": "Indicates if the column may contain Null values; possible values are true and false. Default is false." + }, + "isUnique": { + "type": "boolean", + "default": false, + "description": "Indicates if the column contains unique values; possible values are true and false. Default is false." + }, + "partitionStatus": { + "type": "boolean", + "default": false, + "description": "Indicates if the column is partitioned; possible values are true and false." + }, + "partitionKeyPosition": { + "type": "integer", + "default": -1, + "description": "If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1." + }, + "clusterStatus": { + "type": "boolean", + "default": false, + "description": "Indicates of the column is clustered; possible values are true and false." + }, + "clusterKeyPosition": { + "type": "integer", + "default": -1, + "description": "If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1." + }, + "classification": { + "type": "string", + "description": "Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5.", + "examples": ["confidential", "restricted", "public"] + }, + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "encryptedColumnName": { + "type": "string", + "description": "The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`." + }, + "transformSourceTables": { + "type": "array", + "description": "List of sources used in column transformation.", + "items": { + "type": "string" + } + }, + "transformLogic": { + "type": "string", + "description": "Logic used in the column transformation." + }, + "transformDescription": { + "type": "string", + "description": "Describes the transform logic in very simple terms." + }, + "sampleValues": { + "type": "array", + "description": "List of sample column values.", + "items": { + "type": "string" + } + }, + "criticalDataElementStatus": { + "type": "boolean", + "default": false, + "description": "True or false indicator; If element is considered a critical data element (CDE) then true else false." + }, + "tags": { + "type": "array", + "description": "A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level.", + "items": { + "type": "string" + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "logicalType": { + "const": "string" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { + "properties": { + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length of the string." + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length of the string." + }, + "pattern": { + "type": "string", + "format": "regex", + "description": "Regular expression pattern to define valid value. Follows regular expression syntax from ECMA-262 (https://262.ecma-international.org/5.1/#sec-15.10.1)." + }, + "format": { + "type": "string", + "examples": ["password", "byte", "binary", "email", "uuid", "uri", "hostname", "ipv4", "ipv6"], + "description": "Provides extra context about what format the string follows." + } + }, + "additionalProperties": false + } + } + } + }, { + "if": { + "properties": { + "logicalType": { + "const": "date" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { + "properties": { + "format": { + "type": "string", + "examples": ["yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "HH:mm:ss"], + "description": "Format of the date. Follows the format as prescribed by [JDK DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). For example, format 'yyyy-MM-dd'." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "maximum": { + "type": "string", + "description": "All date values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "minimum": { + "type": "string", + "description": "All date values are greater than or equal to this value (values >= minimum)." + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "anyOf": [ + { + "properties": { + "logicalType": { + "const": "number" + } + } + }, + { + "properties": { + "logicalType": { + "const": "integer" + } + } + } + ] + }, + "then": { + "properties": { + "logicalTypeOptions": { + "properties": { + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0, + "description": "Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5." + }, + "maximum": { + "type": "number", + "description": "All values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "minimum": { + "type": "number", + "description": "All values are greater than or equal to this value (values >= minimum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "format": { + "type": "string", + "default": "i32", + "description": "Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types).", + "enum": ["i8", "i16", "i32", "i64", "i128", "u8", "u16", "u32", "u64", "u128"] + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "object" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { + "properties": { + "maxProperties": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of properties." + }, + "minProperties": { + "type": "integer", + "minimum": 0, + "default": 0, + "description": "Minimum number of properties." + }, + "required": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "uniqueItems": true, + "description": "Property names that are required to exist in the object." + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "array" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { + "properties": { + "maxItems": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of items." + }, + "minItems": { + "type": "integer", + "minimum": 0, + "default": 0, + "description": "Minimum number of items" + }, + "uniqueItems": { + "type": "boolean", + "default": false, + "description": "If set to true, all items in the array are unique." + } + }, + "additionalProperties": false + } + } + } + } + ], + "required": ["column", "logicalType", "physicalType"] + }, + "DataQuality": { + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "The Rosewall data quality code(s) indicating which quality checks need to be performed at the dataset, table or column level; The quality keyword may appear at any level; Some quality checks require parameters such so the check can be completed (eg, list of fields used to identify a distinct row) therefore some quality checks may be followed by a single value or an array; See appendix for link to quality checks." + }, + "templateName": { + "type": "string", + "description": "The template name which indicates what is the equivalent template from the tool." + }, + "description": { + "type": "string", + "description": "Describe the quality check to be completed." + }, + "toolName": { + "type": "string", + "description": "Name of the tool used to complete the quality check; Most will be Elevate initially." + }, + "toolRuleName": { + "type": "string", + "description": "Name of the quality tool's rule created to complete the quality check." + }, + "dimension": { + "type": "string", + "description": "The key performance indicator (KPI) or dimension for data quality." + }, + "columns": { + "type": "string", + "description": "List of columns to be used in the quality check." + }, + "column": { + "type": "string", + "description": "To be used in lieu of quality.columns when only a single column is required for the quality check." + }, + "type": { + "type": "string", + "description": "The type of quality check." + }, + "severity": { + "type": "string", + "description": "The severance of the quality rule." + }, + "businessImpact": { + "type": "string", + "description": "Consequences of the rule failure." + }, + "scheduleCronExpression": { + "type": "string", + "description": "Rule execution schedule details." + }, + "customProperties": { + "type": "array", + "description": "Additional properties required for rule execution.", + "items": { + "$ref": "#/$defs/CustomProperty" + } + } + }, + "required": ["templateName", "toolName"] + }, + "AuthoritativeDefinitions": { + "type": "array", + "description": "List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "URL to the authority." + }, + "type": { + "type": "string", + "description": "Type of definition for authority: v2.3 adds standard values: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`.", + "examples": ["businessDefinition", "transformationImplementation", "videoTutorial", "tutorial", "implementation"] + } + }, + "required": ["url", "type"] + } + }, + "Pricing": { + "type": "object", + "properties": { + "priceAmount": { + "type": "number", + "description": "Subscription price per unit of measure in `priceUnit`." + }, + "priceCurrency": { + "type": "string", + "description": "Currency of the subscription price in `price.priceAmount`." + }, + "priceUnit": { + "type": "string", + "description": "The unit of measure for calculating cost. Examples megabyte, gigabyte." + } + } + }, + "Stakeholder": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The stakeholder's username or email." + }, + "role": { + "type": "string", + "description": "The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role." + }, + "dateIn": { + "type": "string", + "description": "The date when the user became a stakeholder." + }, + "dateOut": { + "type": "string", + "description": "The date when the user ceased to be a stakeholder" + }, + "replacedByUsername": { + "type": "string", + "description": "The username of the user who replaced the stakeholder" + } + } + }, + "Role": { + "type": "object", + "properties": { + "role": { + "type": "string", + "description": "Name of the IAM role that provides access to the dataset; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + }, + "access": { + "type": "string", + "description": "The type of access provided by the IAM role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + }, + "firstLevelApprovers": { + "type": "string", + "description": "The name(s) of the first level approver(s) of the role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + }, + "secondLevelApprovers": { + "type": "string", + "description": "The name(s) of the second level approver(s) of the role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + } + }, + "required": ["role", "access"] + }, + "ServiceLevelAgreementProperty": { + "type": "object", + "properties": { + "property": { + "type": "string", + "description": "Specific property in SLA, check the periodic table. May requires units (more details to come)." + }, + "value": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Agreement value. The label will change based on the property itself." + }, + "valueExt": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Extended agreement value. The label will change based on the property itself." + }, + "unit": { + "type": "string", + "description": "**d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard." + }, + "column": { + "type": "string", + "description": "Column(s) to check on. Multiple columns should be extremely rare and, if so, separated by commas." + }, + "driver": { + "type": "string", + "description": "Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`.", + "examples": ["regulatory", "analytics", "operational"] + } + }, + "required": ["property", "value"] + }, + "CustomProperty": { + "type": "object", + "properties": { + "property": { + "type": "string", + "description": "The name of the key. Names should be in camel case–the same as if they were permanent properties in the contract." + }, + "value": { + "type": "object", + "description": "The value of the key." + } + } + } + } +} \ No newline at end of file From 7d0758bbd4369481f8894eea47abc854aeecfb4f Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Sat, 13 Jul 2024 18:11:36 +0800 Subject: [PATCH 04/93] Split up number and integer formats, allow f32 and f64 format for numbers --- .../data-types/all-data-types.odcs.yaml | 1 + schema/odcs-json-schema-latest.json | 54 +++++++++++++++++-- schema/odcs-json-schema-v3.0.0.json | 54 +++++++++++++++++-- 3 files changed, 99 insertions(+), 10 deletions(-) diff --git a/docs/examples/data-types/all-data-types.odcs.yaml b/docs/examples/data-types/all-data-types.odcs.yaml index a8231f5..66dc53c 100644 --- a/docs/examples/data-types/all-data-types.odcs.yaml +++ b/docs/examples/data-types/all-data-types.odcs.yaml @@ -36,6 +36,7 @@ dataset: logicalType: number logicalTypeOptions: minimum: 0 + format: f32 - column: age physicalType: int logicalType: integer diff --git a/schema/odcs-json-schema-latest.json b/schema/odcs-json-schema-latest.json index 83580f5..81cce37 100644 --- a/schema/odcs-json-schema-latest.json +++ b/schema/odcs-json-schema-latest.json @@ -416,14 +416,58 @@ { "properties": { "logicalType": { - "const": "number" + "const": "integer" } } - }, + } + ] + }, + "then": { + "properties": { + "logicalTypeOptions": { + "properties": { + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0, + "description": "Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5." + }, + "maximum": { + "type": "number", + "description": "All values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "minimum": { + "type": "number", + "description": "All values are greater than or equal to this value (values >= minimum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "format": { + "type": "string", + "default": "i32", + "description": "Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types).", + "enum": ["i8", "i16", "i32", "i64", "i128", "u8", "u16", "u32", "u64", "u128"] + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "anyOf": [ { "properties": { "logicalType": { - "const": "integer" + "const": "number" } } } @@ -459,8 +503,8 @@ "format": { "type": "string", "default": "i32", - "description": "Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types).", - "enum": ["i8", "i16", "i32", "i64", "i128", "u8", "u16", "u32", "u64", "u128"] + "description": "Format of the value in terms of how many bits of space it can use (follows the Rust float types).", + "enum": ["f32", "f64"] } }, "additionalProperties": false diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 83580f5..81cce37 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -416,14 +416,58 @@ { "properties": { "logicalType": { - "const": "number" + "const": "integer" } } - }, + } + ] + }, + "then": { + "properties": { + "logicalTypeOptions": { + "properties": { + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0, + "description": "Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5." + }, + "maximum": { + "type": "number", + "description": "All values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "minimum": { + "type": "number", + "description": "All values are greater than or equal to this value (values >= minimum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "format": { + "type": "string", + "default": "i32", + "description": "Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types).", + "enum": ["i8", "i16", "i32", "i64", "i128", "u8", "u16", "u32", "u64", "u128"] + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "anyOf": [ { "properties": { "logicalType": { - "const": "integer" + "const": "number" } } } @@ -459,8 +503,8 @@ "format": { "type": "string", "default": "i32", - "description": "Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types).", - "enum": ["i8", "i16", "i32", "i64", "i128", "u8", "u16", "u32", "u64", "u128"] + "description": "Format of the value in terms of how many bits of space it can use (follows the Rust float types).", + "enum": ["f32", "f64"] } }, "additionalProperties": false From 0606c37937897ec1c0be7667018eee16c6fd1849 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Fri, 26 Jul 2024 17:08:46 -0400 Subject: [PATCH 05/93] Integration of RFC 4 --- CHANGELOG.md | 35 ++++++++ docs/standard.md | 212 +++++++++++++++++++++++------------------------ 2 files changed, 139 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83a3485..bdcea5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,41 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color This document tracks the history and evolution of the **Open Data Contract Standard**. +# v3.0.0 - 2024-xx-xx - IN PROGRESS + +* Fundamentals: +* Schema: + * Major changes, check spec. + * Adds support for non table formats, hierarchies, and arrays. + * `priorTableName` is not supported anymore, if needed, consider a custom property. + * `dataGranularity` is now `dataGranularityDescription`. + * `encryptedColumnName`is now `encryptedName`. + * `partitionStatus` is now `partitioned`. + * 'clusterStatus' is not supported anymore, if needed, consider a custom property. + * 'clusterKeyPosition' is not supported anymore, if needed, consider a custom property. + * 'sampleValues' is now 'examples'. + * 'isNullable' is now 'required'. + * 'isUnique' is now 'unique'. + * 'isPrimaryKey' is now 'primaryKey'. + * 'criticalDataElementStatus' is now 'criticalDataElement'. + * 'clusterKeyPosition' is not supported anymore, if needed, consider a custom property. +* Data Quality: + * +* Pricing: + * No changes. +* Team: + * Replaces `stakeholders`. Content stays the same. +* Security: + * No changes. +* SLA: + * Starting with v3, the schema is not purely tables and columns, hence minor modifications: columns are now elements. + * 'slaDefaultColumn' is now 'slaDefaultElement'. + * 'column' is now 'element'. + * Explicit reference to Data QoS. +* Custom and other properties: + * 'systemInstance' is not supported anymore, if needed, consider a custom property. + + # v2.2.2 - 2024-05-23 - APPROVED * In JSON schema validation: diff --git a/docs/standard.md b/docs/standard.md index 99884b7..33e22f9 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -11,15 +11,15 @@ This document describes the keys and values expected in a YAML data contract, pe ## Table of content -* [Fundamentals & demographics](#demographics) -* [Datasets & schema](#dataset-and-schema) +* [Fundamentals (fka demographics)](#demographics) +* [Schema](#dataset-and-schema) * [Data quality](#data-quality) * [Pricing](#pricing) -* [Stakeholders](#stakeholders) +* [Team](#stakeholders) * [Roles](#roles) * [Service-level agreement](#service-level-agreement) -* [Other properties](#other-properties) -* [Full example](#full-example) +* [Custom & other properties](#other-properties) +* [Examples](#full-example) ## Notes @@ -27,7 +27,7 @@ This document describes the keys and values expected in a YAML data contract, pe * Some fields have `null` value: even if it is equivalent to not having the field in the contract, we wanted to have the field for illustration purpose. * This contract leverages BigQuery but should be **platform agnostic**. If you think it is not the case, please raise an [issue](https://github.com/AIDAUserGroup/open-data-contract-standard/issues). -## Demographics +## Fundamentals This section contains general information about the contract. ### Example @@ -112,38 +112,37 @@ tags: null | password | Password | No | User credentials for connecting to the dataset; how the credentials will be stored/passed is out of the scope of this contract. | | schedulerAppName | Scheduler App Name | No | Required if you want to schedule stuff. The name of the application used to schedule jobs | -## Dataset and schema +## Schema This section describes the dataset and the schema of the data contract. It is the support for data quality, which is detailed in the next section. ### Example ```YAML -dataset: - - table: tbl - physicalName: tbl_1 # NEW in v2.1.0, Optional, default value is table name + version separated by underscores, as table_1_2_0 - priorTableName: null # if needed +schema: + - name: tbl + logicalType: object + physicalType: table + physicalName: tbl_1 description: Provides core payment metrics - authoritativeDefinitions: # NEW in v2.2.0, inspired by the column-level authoritative links + authoritativeDefinitions: - url: https://catalog.data.gov/dataset/air-quality type: businessDefinition - url: https://youtu.be/jbY1BKFj9ec type: videoTutorial tags: null - dataGranularity: Aggregation on columns txn_ref_dt, pmt_txn_id - columns: - - column: txn_ref_dt - isPrimaryKey: false # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. + dataGranularityDescription: Aggregation on columns txn_ref_dt, pmt_txn_id + properties: + - name: txn_ref_dt + primaryKey: false primaryKeyPosition: -1 businessName: transaction reference date logicalType: date physicalType: date - isNullable: false + required: false description: null - partitionStatus: true + partitioned: true partitionKeyPosition: 1 - clusterStatus: false - clusterKeyPosition: -1 - criticalDataElementStatus: false + criticalDataElement: false tags: [] classification: public transformSourceTables: @@ -152,38 +151,34 @@ dataset: - table_name_3 transformLogic: sel t1.txn_dt as txn_ref_dt from table_name_1 as t1, table_name_2 as t2, table_name_3 as t3 where t1.txn_dt=date-3 transformDescription: Defines the logic in business terms. - sampleValues: + examples: - 2022-10-03 - 2020-01-28 - - column: rcvr_id - isPrimaryKey: true # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. + - name: rcvr_id + primaryKey: true primaryKeyPosition: 1 businessName: receiver id logicalType: string physicalType: varchar(18) - isNullable: false + required: false description: A description for column rcvr_id. - partitionStatus: false + partitioned: false partitionKeyPosition: -1 - clusterStatus: true - clusterKeyPosition: 1 - criticalDataElementStatus: false + criticalDataElement: false tags: [] classification: restricted - encryptedColumnName: enc_rcvr_id - - column: rcvr_cntry_code - isPrimaryKey: false # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. + encryptedName: enc_rcvr_id + - name: rcvr_cntry_code + primaryKey: false primaryKeyPosition: -1 businessName: receiver country code logicalType: string physicalType: varchar(2) - isNullable: false + required: false description: null - partitionStatus: false + partitioned: false partitionKeyPosition: -1 - clusterStatus: false - clusterKeyPosition: -1 - criticalDataElementStatus: false + criticalDataElement: false tags: [] classification: public authoritativeDefinitions: @@ -193,43 +188,44 @@ dataset: type: transformationImplementation - url: jdbc:postgresql://localhost:5432/adventureworks/tbl_1/rcvr_cntry_code type: implementation - encryptedColumnName: rcvr_cntry_code_encrypted + encryptedName: rcvr_cntry_code_encrypted ``` ### Definitions +Note: the description needs to be updated. + | Key | UX label | Required | Description | |--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| dataset | Dataset | Yes | Array. A list of tables within the dataset to be cataloged. | -| dataset.table | Table | Yes | Name of the table being cataloged; the value should only contain the table name. Do not include the project or dataset name in the value. | -| dataset.table.physicalName | Physical Name | No | Physical name of the table, default value is table name + version separated by underscores, as `table_1_2_0`. | -| dataset.table.priorTableName | Prior Table Name | No | Name of the previous version of the dataset, if applicable. | -| dataset.table.description | Description | No | Description of the dataset. | -| dataset.table.authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard. | -| dataset.table.dataGranularity | Data Granularity | No | Granular level of the data in the table. Example would be `pmt_txn_id`. | -| dataset.table.columns | Columns | Yes | Array. A list of columns in the table. | -| dataset.table.columns.column | Column | Yes | The name of the column. | -| dataset.table.columns.column.isPrimaryKey | Primary Key | No | Boolean value specifying whether the column is primary or not. Default is false. | -| dataset.table.columns.column.primaryKeyPosition | Primary Key Position | No | If column is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1. | -| dataset.table.columns.column.businessName | Business Name | No | The business name of the column. | -| dataset.table.columns.column.logicalType | Logical Type | Yes | The logical column datatype. | -| dataset.table.columns.column.physicalType | Physical Type | Yes | The physical column datatype. | -| dataset.table.columns.column.description | Description | No | Description of the column. | -| dataset.table.columns.column.isNullable | Nullable | No | Indicates if the column may contain Null values; possible values are true and false. Default is false. | -| dataset.table.columns.column.isUnique | Unique | No | Indicates if the column contains unique values; possible values are true and false. Default is false. | -| dataset.table.columns.column.partitionStatus | Partition Status | No | Indicates if the column is partitioned; possible values are true and false. | -| dataset.table.columns.column.partitionKeyPosition | Partition Key Position | No | If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1. | -| dataset.table.columns.column.clusterStatus | Cluster Status | No | Indicates of the column is clustered; possible values are true and false. | -| dataset.table.columns.column.clusterKeyPosition | Cluster Key Position | No | If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1. | -| dataset.table.columns.column.classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5. | -| dataset.table.columns.column.authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on column logic or values; examples would be URL to a GitHub repo, Collibra, on another tool. | -| dataset.table.columns.column.encryptedColumnName | Encrypted Column Name | No | The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`. | -| dataset.table.columns.column.transformSourceTables | Transform Source Tables | No | List of sources used in column transformation. | -| dataset.table.columns.column.transformLogic | Transform Logic | No | Logic used in the column transformation. | -| dataset.table.columns.column.transformDescription | Transform Description | No | Describes the transform logic in very simple terms. | -| dataset.table.columns.column.sampleValues | Sample Values | No | List of sample column values. | -| dataset.table.columns.column.criticalDataElementStatus | Critical Data Element Status | No | True or false indicator; If element is considered a critical data element (CDE) then true else false. | -| dataset.table.columns.column.tags | Tags | No | A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level. | +| schema | schema | Yes | Array. A list of tables within the schema to be cataloged. | +| schema.table | Table | Yes | Name of the table being cataloged; the value should only contain the table name. Do not include the project or schema name in the value. | +| schema.table.physicalName | Physical Name | No | Physical name of the table, default value is table name + version separated by underscores, as `table_1_2_0`. | +| schema.table.description | Description | No | Description of the schema. | +| schema.table.authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard. | +| schema.table.dataGranularity | Data Granularity | No | Granular level of the data in the table. Example would be `pmt_txn_id`. | +| schema.table.columns | Columns | Yes | Array. A list of columns in the table. | +| schema.table.columns.column | Column | Yes | The name of the column. | +| schema.table.columns.column.isPrimaryKey | Primary Key | No | Boolean value specifying whether the column is primary or not. Default is false. | +| schema.table.columns.column.primaryKeyPosition | Primary Key Position | No | If column is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1. | +| schema.table.columns.column.businessName | Business Name | No | The business name of the column. | +| schema.table.columns.column.logicalType | Logical Type | Yes | The logical column datatype. | +| schema.table.columns.column.physicalType | Physical Type | Yes | The physical column datatype. | +| schema.table.columns.column.description | Description | No | Description of the column. | +| schema.table.columns.column.isNullable | Nullable | No | Indicates if the column may contain Null values; possible values are true and false. Default is false. | +| schema.table.columns.column.isUnique | Unique | No | Indicates if the column contains unique values; possible values are true and false. Default is false. | +| schema.table.columns.column.partitionStatus | Partition Status | No | Indicates if the column is partitioned; possible values are true and false. | +| schema.table.columns.column.partitionKeyPosition | Partition Key Position | No | If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1. | +| schema.table.columns.column.clusterStatus | Cluster Status | No | Indicates of the column is clustered; possible values are true and false. | +| schema.table.columns.column.clusterKeyPosition | Cluster Key Position | No | If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1. | +| schema.table.columns.column.classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5. | +| schema.table.columns.column.authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on column logic or values; examples would be URL to a GitHub repo, Collibra, on another tool. | +| schema.table.columns.column.encryptedColumnName | Encrypted Column Name | No | The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`. | +| schema.table.columns.column.transformSourceTables | Transform Source Tables | No | List of sources used in column transformation. | +| schema.table.columns.column.transformLogic | Transform Logic | No | Logic used in the column transformation. | +| schema.table.columns.column.transformDescription | Transform Description | No | Describes the transform logic in very simple terms. | +| schema.table.columns.column.sampleValues | Sample Values | No | List of sample column values. | +| schema.table.columns.column.criticalDataElementStatus | Critical Data Element Status | No | True or false indicator; If element is considered a critical data element (CDE) then true else false. | +| schema.table.columns.column.tags | Tags | No | A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level. | | ### Authorative definitions @@ -244,15 +240,16 @@ Updated in ODCS (Open Data Contract Standard) v2.2.1. ## Data quality This section describes data quality rules & parameters. They are tightly linked to the schema described in the previous section. -### Example of data quality at the dataset level +### Example of data quality at the object level Note: * This example relies on a data quality tool called Elevate. It should be easily transformed to any other tool. If you have questions, please raise an [issue](https://github.com/AIDAUserGroup/open-data-contract-standard/issues). * The Open Data Contract Standard has a provision for supporting multiple data quality tools. ```YAML -dataset: - - table: tab1 +schema: + - name: tab1 + logicalType: object # ... quality: - code: countCheck # Required, name of the rule @@ -300,13 +297,14 @@ dataset: value: ``` -### Example of data quality at the column level +### Example of data quality at the element level ```YAML -dataset: - - table: tab1 - - column: rcvr_id - isPrimaryKey: true # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. +schema: + - name: tab1 + logicalType: object + - name: rcvr_id + primaryKey: true # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. businessName: receiver id # ... quality: @@ -370,12 +368,12 @@ price: | price.priceUnit | Price Unit | No | The unit of measure for calculating cost. Examples megabyte, gigabyte. | -## Stakeholders -This section lists stakeholders and the history of their relation with this data contract. +## Team +This section lists team members and the history of their relation with this data contract. In v2.x, this section was called stakeholders. ### Example ```YAML -stakeholders: +team: - username: ceastwood role: Data Scientist dateIn: 2022-08-02 @@ -393,14 +391,14 @@ stakeholders: ### Definitions The UX label is the label used in the UI and other user experiences. It is not limited to BlueRacket. -| Key | UX label | Required | Description | -|---------------------------------|----------------------------|----------|---------------------------------------------------------------------------------------------------| -| stakeholders | Stakeholders | No | Array | -| stakeholders.username | Username | No | The stakeholder's username or email. | -| stakeholders.role | Role | No | The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role. | -| stakeholders.dateIn | Date In | No | The date when the user became a stakeholder. | -| stakeholders.dateOut | Date Out | No | The date when the user ceased to be a stakeholder | -| stakeholders.replacedByUsername | Replaced By Username | No | The username of the user who replaced the stakeholder | +| Key | UX label | Required | Description | +|-------------------------|--------------------|----------|---------------------------------------------------------------------------------------------------| +| team | Stakeholders | No | Array | +| team.username | Username | No | The stakeholder's username or email. | +| team.role | Role | No | The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role. | +| team.dateIn | Date In | No | The date when the user became a stakeholder. | +| team.dateOut | Date Out | No | The date when the user ceased to be a stakeholder | +| team.replacedByUsername | Replaced By | No | The username of the user who replaced the stakeholder | ## Roles @@ -438,8 +436,8 @@ roles: | roles.firstLevelApprovers | 1st Level Approvers | No | The name(s) of the first-level approver(s) of the role; the value will generally come directly from the "BQ dataset to IAM roles mapping" document. | | roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role; the value will generally come directly from the "BQ dataset to IAM roles mapping" document. | -## Service-level agreement -This section describes the service-level agreements (SLA). SLA have been extended in version v2.1.0. +## Service-level agreement (SLA) +This section describes the service-level agreements (SLA). SLA have been extended in version v2.1.0. * Use the `Table.Column` to indicate the number to do the checks on, as in `SELECT txn_ref_dt FROM tab1`. * Separate multiple table.columns by a comma, as in `table1.col1`, `table2.col1`, `table1.col2`. @@ -448,12 +446,12 @@ This section describes the service-level agreements (SLA). SLA have been extende ### Example ```YAML -slaDefaultColumn: tab1.txn_ref_dt # Optional, default value is partitionColumn. +slaDefaultElement: tab1.txn_ref_dt # Optional, default value is partitionColumn. slaProperties: - property: latency # Property, see list of values in DP QoS value: 4 unit: d # d, day, days for days; y, yr, years for years - column: tab1.txn_ref_dt # This would not be needed as it is the same table.column as the default one + element: tab1.txn_ref_dt # This would not be needed as it is the same table.column as the default one - property: generalAvailability value: 2022-05-12T09:30:10-08:00 - property: endOfSupport @@ -463,34 +461,35 @@ slaProperties: - property: retention value: 3 unit: y - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt - property: frequency value: 1 valueExt: 1 unit: d - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt - property: timeOfAvailability value: 09:00-08:00 - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt driver: regulatory # Describes the importance of the SLA: [regulatory|analytics|operational|...] - property: timeOfAvailability value: 08:00-08:00 - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt driver: analytics ``` ### Definitions -| Key | UX label | Required | Description | -|------------------------|-----------------------|--------------------------------|----------------------------------------------------------------------------------------------------------------------------| -| slaDefaultColumn | Default SLA column(s) | No | Columns (using the Table.Column notation) to do the checks on. By default, it is the partition column. | -| slaProperties | SLA | No | A list of key/value pairs for SLA specific properties. There is no limit on the type of properties (more details to come). | -| slaProperties.property | Property | Yes | Specific property in SLA, check the periodic table. May requires units (more details to come). | -| slaProperties.value | Value | Yes | Agreement value. The label will change based on the property itself. | -| slaProperties.valueExt | Extended value | No - unless needed by property | Extended agreement value. The label will change based on the property itself. | -| slaProperties.unit | Unit | No - unless needed by property | **d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard. | -| slaProperties.column | Column(s) | No | Column(s) to check on. Multiple columns should be extremely rare and, if so, separated by commas. | -| slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | +| Key | UX label | Required | Description | +|------------------------|------------------------|--------------------------------|----------------------------------------------------------------------------------------------------------------------------| +| slaDefaultElement | Default SLA element(s) | No | Element (using the element path notation) to do the checks on. | +| slaProperties | SLA | No | A list of key/value pairs for SLA specific properties. There is no limit on the type of properties. | +| slaProperties.property | Property | Yes | Specific property in SLA, check the Data QoS periodic table. May requires units. | +| slaProperties.value | Value | Yes | Agreement value. The label will change based on the property itself. | +| slaProperties.valueExt | Extended value | No - unless needed by property | Extended agreement value. The label will change based on the property itself. | +| slaProperties.unit | Unit | No - unless needed by property | **d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard. | +| slaProperties.element | Element(s) | No | Element(s) to check on. Multiple elements should be extremely rare and, if so, separated by commas. | +| slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | + ## Other properties This section covers other properties you may find in a data contract. @@ -506,11 +505,9 @@ customProperties: - property: dataprocClusterName # Used for specific applications like Elevate value: [cluster name] -systemInstance: instance.ClimateQuantum.org contractCreatedTs: 2022-11-15 02:59:43 ``` - ### Definitions | Key | UX label | Required | Description | @@ -518,7 +515,6 @@ contractCreatedTs: 2022-11-15 02:59:43 | customProperties | Custom Properties | No | A list of key/value pairs for custom properties. Initially created to support the REF ruleset property. | | customProperties.property | Property | No | The name of the key. Names should be in camel case–the same as if they were permanent properties in the contract. | | customProperties.value | Value | No | The value of the key. | -| systemInstance | System Instance | No | System Instance name where the dataset resides. | | contractCreatedTs | Contract Created UTC | No | Timestamp in UTC of when the data contract was created. | From 7c85c2429a1a9d541d278c92cfd773dc1ab753fa Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 27 Jul 2024 07:26:13 +0200 Subject: [PATCH 06/93] Updates from https://github.com/bitol-io/tsc/blob/main/rfcs/0005-clean-implementation-specific.md (top-level) --- docs/standard.md | 90 ++++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 64 deletions(-) diff --git a/docs/standard.md b/docs/standard.md index 33e22f9..e7187f5 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -33,45 +33,21 @@ This section contains general information about the contract. ### Example ```YAML -# What's this data contract about? -datasetDomain: seller # Domain -quantumName: my quantum # Data product name -userConsumptionMode: Analytical -version: 1.1.0 # Version (follows semantic versioning) -status: current -uuid: 53581432-6c55-4ba2-a65f-72344a91553a - -# Lots of information +apiVersion: 3.0.0 # Standard version +kind: DataContract + +id: 53581432-6c55-4ba2-a65f-72344a91553a +name: seller_payments_v1 +version: 1.1.0 # Data Contract Version +status: production +domain: seller +dataProduct: payments +tenant: ClimateQuantumInc + description: purpose: Views built on top of the seller tables. limitations: null usage: null -tenant: ClimateQuantumInc - -# Getting support -productDl: product-dl@ClimateQuantum.org -productSlackChannel: '#product-help' -productFeedbackUrl: null - -# Physical parts / GCP / BigQuery specific -sourcePlatform: googleCloudPlatform -sourceSystem: bigQuery -project: edw # BQ dataset -datasetName: access_views # BQ dataset - -kind: DataContract -apiVersion: 2.3.0 # Standard version (follows semantic versioning, previously known as templateVersion) - -type: tables - -# Physical access -driver: null -driverVersion: null -server: null -database: pypl-edw.pp_access_views -username: '${env.username}' -password: '${env.password}' -schedulerAppName: name_coming_from_scheduler # NEW 2.1.0 Required if you want to schedule stuff, comes from DataALM. # Data Quality quality: null # See more information below @@ -82,35 +58,21 @@ tags: null ### Definitions -| Key | UX label | Required | Description | -|-------------------------|--------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| datasetDomain | Dataset domain | No | Name of the logical domain dataset the contract describes. This field is only required for output data contracts. Examples: `imdb_ds_aggregate`, `receiver_profile_out`, `transaction_profile_out`. | -| quantumName | Quantum name | Yes | The name of the data quantum or data product. | -| userConsumptionMode | Consumption mode | No | List of data modes for which the dataset may be used. Expected sample values might be `analytical` or `operational`.
Note: in the future, this will probably be replaced by ports. | -| version | Version | Yes | Current version of the data contract. | -| status | Status | Yes | Current status of the dataset. Valid values are `production`, `test`, or `development`. | -| uuid | Identifier | Yes | A unique identifier used to reduce the risk of dataset name collisions; initially the UUID will be created using a UUID generator tool ([example](https://www.uuidgenerator.net/)). However, we may want to develop a method that accepts a seed value using a combination of fields–such as name, kind and source–to create a repeatable value. | -| description | Description | No | Object. | -| description.purpose | Purpose | No | Purpose of the dataset, table, or column (depending on the level); the key may appear at the dataset, table, or column level. | -| description.limitations | Limitations | No | Limitations of the dataset, table, or column (depending on the level); the key may appear at the dataset, table, or column level. | -| description.usage | Usage | No | Intended usage of the dataset, table, or column (depending on the level); the key may appear at the dataset, table, or column level. | -| tenant | Tenant | No | Indicates the property the data is primarily associated with. Value is case insensitive. | -| productDl | E-mail distribution list | No | The email distribution list (DL) of the persons or team responsible for maintaining the dataset. | -| productSlackChannel | Support Slack channel | No | Slack channel of the team responsible for maintaining the dataset. | -| productFeedbackUrl | Feedback URL | No | The URL for submitting feedback to the team responsible for maintaining the dataset. | -| sourcePlatform | Source platform | No | The platform where the dataset resides. Expected value is GoogleCloudPlatform, IBMCloud, Azure... | -| sourceSystem | Source system | No | The system where the dataset resides. Expected value can be BigQuery. | -| project | Project | No | Associated cloud project name, can be used for billing or administrative purpose. Used to be datasetProject. | -| datasetName | Dataset name | No | May be required in cloud instance like GCP BigQuery dataset name. | -| server | Server | No | The server where the dataset resides. | -| kind | Kind | Yes | The kind of file this is. Valid value is `DataContract`. | -| apiVersion | Standard version | No | Version of the standard used to build data contract. Default value is v2.2.2. | -| type | Type | Yes | Identifies the types of objects in the dataset. For BigQuery or any other database, the expected value would be Tables. | -| driver | Driver | No | The connection driver required to connect to the dataset. | -| driverVersion | Driver version | No | The version of the connection driver to be used to connect to the dataset. | -| username | Username | No | User credentials for connecting to the dataset; how the credentials will be stored/passed is outside of the scope of the contract. | -| password | Password | No | User credentials for connecting to the dataset; how the credentials will be stored/passed is out of the scope of this contract. | -| schedulerAppName | Scheduler App Name | No | Required if you want to schedule stuff. The name of the application used to schedule jobs | +| Key | UX label | Required | Description | +|-------------------------|------------------|----------|------------------------------------------------------------------------------------------| +| apiVersion | Standard version | Yes | Version of the standard used to build data contract. Default value is `v3.0.0`. | +| kind | Kind | Yes | The kind of file this is. Valid value is `DataContract`. | +| id | ID | Yes | A unique identifier used to reduce the risk of dataset name collisions, such as a UUID. | +| name | Name | No | Name of the data contract. | +| version | Version | Yes | Current version of the data contract. | +| status | Status | Yes | Current status of the data contract. | +| tenant | Tenant | No | Indicates the property the data is primarily associated with. Value is case insensitive. | +| domain | Domain | No | Name of the logical data domain. | +| dataProduct | Data Product | No | The name of the data product. | +| description | Description | No | Object. | +| description.purpose | Purpose | No | What is the intendet purpose for the provided data. | +| description.limitations | Limitations | No | Technical, compliance, and legal limitations for using the data. | +| description.usage | Usage | No | How to use the data. | ## Schema This section describes the dataset and the schema of the data contract. It is the support for data quality, which is detailed in the next section. From 5346e158eb29f98379f11b08dc4905007a43110d Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 27 Jul 2024 07:30:00 +0200 Subject: [PATCH 07/93] Update CHANGELOG --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdcea5d..5d2ed14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,26 @@ This document tracks the history and evolution of the **Open Data Contract Stand # v3.0.0 - 2024-xx-xx - IN PROGRESS * Fundamentals: + * Rename uuid to id + * Add name + * Rename quantumName to dataProduct and make it optional + * Rename datasetDomain to domain (we avoid the dataset prefix) + * Drop datasetKind (example: virtualDataset, was optional, have not seen any * usage) + * Drop userConsumptionMode (examples: analytical, was optional, already * deprecated in v2.) + * Drop sourceSystem (example: bigQuery, information will be encoded in servers) + * Drop sourcePlatform (example: googleCloudPlatform, information will be encoded * in servers) + * Drop productSlackChannel (will move to support channels) + * Drop productFeedbackUrl (will move to support channels) + * Drop productDl (will move to support channels) + * Drop username (credentials should not be stored in the data contract) + * Drop password (credentials should not be stored in the data contract) + * Drop driverVersion (will move to servers if needed) + * Drop driver (will move to servers if needed) + * Drop server (will move to servers if needed) + * Drop project (BigQuery-specific, will move to servers) + * Drop datasetName (BigQuery-specific, will move to servers) + * Drop database (BigQuery-specific, will move to servers) + * Drop schedulerAppName (not part of the contract) * Schema: * Major changes, check spec. * Adds support for non table formats, hierarchies, and arrays. From 305d6df0b74f3d6d3d3b00d896518757943f73fa Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 27 Jul 2024 07:35:27 +0200 Subject: [PATCH 08/93] Update Roles --- CHANGELOG.md | 3 +++ docs/standard.md | 9 +++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d2ed14..6d3ca78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,9 @@ This document tracks the history and evolution of the **Open Data Contract Stand * No changes. * Team: * Replaces `stakeholders`. Content stays the same. +* Role: + * Added `description` + * Changed `access` is not required anymore * Security: * No changes. * SLA: diff --git a/docs/standard.md b/docs/standard.md index e7187f5..36913fc 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -393,10 +393,11 @@ roles: | Key | UX label | Required | Description | |----------------------------|---------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------| | roles | Roles | Yes | Array. A list of roles that will provide user access to the dataset. | -| roles.role | Role | Yes | Name of the IAM role that provides access to the dataset; the value will generally come directly from the "BQ dataset to IAM roles mapping" document. | -| roles.access | Access | Yes | The type of access provided by the IAM role; the value will generally come directly from the "BQ dataset to IAM roles mapping" document. | -| roles.firstLevelApprovers | 1st Level Approvers | No | The name(s) of the first-level approver(s) of the role; the value will generally come directly from the "BQ dataset to IAM roles mapping" document. | -| roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role; the value will generally come directly from the "BQ dataset to IAM roles mapping" document. | +| roles.role | Role | Yes | Name of the IAM role that provides access to the datase. | +| roles.description | Description | No | Description of the IAM role and its permissions. | +| roles.access | Access | No | The type of access provided by the IAM role. | +| roles.firstLevelApprovers | 1st Level Approvers | No | The name(s) of the first-level approver(s) of the role. | +| roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role. | ## Service-level agreement (SLA) This section describes the service-level agreements (SLA). SLA have been extended in version v2.1.0. From b6f810bd90a3996940cff79d5bc4d90563f7fa0e Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Mon, 29 Jul 2024 08:52:40 -0400 Subject: [PATCH 09/93] Adding v3 diagram --- docs/img/data-contract-diagram-latest.svg | 450 ++++++++++++++++++++++ docs/img/data-contract-diagram-v3.pdf | Bin 0 -> 43760 bytes docs/img/data-contract-diagram-v3.png | Bin 0 -> 921567 bytes docs/img/data-contract-diagram-v3.svg | 450 ++++++++++++++++++++++ 4 files changed, 900 insertions(+) create mode 100644 docs/img/data-contract-diagram-latest.svg create mode 100644 docs/img/data-contract-diagram-v3.pdf create mode 100644 docs/img/data-contract-diagram-v3.png create mode 100644 docs/img/data-contract-diagram-v3.svg diff --git a/docs/img/data-contract-diagram-latest.svg b/docs/img/data-contract-diagram-latest.svg new file mode 100644 index 0000000..152b428 --- /dev/null +++ b/docs/img/data-contract-diagram-latest.svg @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + Data Contract Vert - v3 + + bg + + + + + + Layer 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Applications + + + + + + Monitoring + + + + + + Observability + + + + + + Notification + + + + + + Tools + + + + + + Enterprise Data + Governance + + + + + + Enterprise Data + Catalog + + + + + + Enterprise Security + & Audit + + + + + + Enterprise Ops + + + + + + Open Data Contract Standard v3 + + + + + + Data Engineers + + + + + + Data Scientists + + + + + + Data Product + Owners + + + + + + Automation Tools + + + + + + + + Name, + Version, + Descriptions… + + + + + + + + History of team + members + + + + + + + + Latency, retention, + frequency… + + + + + + + + Data quality rules, + Data governance + policies + + + + + + + + Logical + representation & + physical + implementation + + + + + + + + Servers, environment, + and storage + + + + + + + + Internal or external + costs associated to + usage + + + + + + + + Roles + + + + + + Fundamentals + + + + + + Schema* + + + + + + SLA + + + + + + Data Quality* + + + + + + Team + + + + + + Infrastructure** + + + + + + Pricing + + + + + + Security + + + + + + + + Enterprise-level consumers & + contributors + + + + + + + + Contributors to the data + contract + + + + + + + + Consumers of the data + contract + + + + + + + + + + + + + + + + + + + + + + + Data QoS applied to + your business needs + + + + + + Business rules*** + + + + + + + + Room for + custom needs + + + + + + Custom + + + + + + + + * Major evolution in v3 + ** New in v3 + *** Scheduled for v3.1 + + + + + + diff --git a/docs/img/data-contract-diagram-v3.pdf b/docs/img/data-contract-diagram-v3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..53392f2b4ed3a1db0925dc614a98fdd49d42b433 GIT binary patch literal 43760 zcmZsiRa9L;x1|qg1fs13-0a~tn=T#x4R$urD}~? zvSy7@4|}X#AEmOmBqJ*mJ3Qs!!R^6W#a-d-;4nNpm<8-;Y6H*D4`!CMwsW&^`PbW- zxLJr>m^qqTfSKhj94y_ez^oi>T&!S0L3md;7Yh@6cu$Cpys=~oowV|&N6cSzQR2NU zd6V)Pn6r?gA`4mbT{I^W+juh2=wj$eD(V8JJ>o)g0b2oeRoNYFd`YmYG0;IyLe3-X zN?Lo&uR`aajY79u6N?uebwZayook;n?;YpLuW&gZp=;&y9_2+jxDk6Ej8&w=xXb9*aVXAfO zclLm?w%uT@k2{UObIaszv}J6#Tp@}d_*uL8Z6tQB)>0e%+Hp}se?HaSL8!Rk-0D=6 z-FB5u05Nvjfz+70<3R95>7u5lc`|oB?$;8|`MJZ*x0X+LzEw7427kOYA>kLp)Pf^1 zA&-Ge{%;YN^WPA=?<>T%NGjgpeVTd@H+J}u2cSC;&nlyAji84y%{>I0n=dt2KG+IK zCr?1*8P2aSD`JOUYnlZK_KPmz8}JYZ7d4Z5%cnB~I}B=d4Ik=UYnn#jjt9h==2+dC zzlZRg%>=d8^_kk!4LkHSMvA}U=~I#1G``REb~V%T_W(k4C&^XJ%Dz=Ei9vKdT&uycW$*F0 zk8@p)N%z`04O?Q?nFM6TFHuISOG9D;`$AK9DWvur+uM_&pELgX=Z)rH&VT^7D4{{xq(bE4BRxI_(L&|>(T^7kc7d& z*aBeE_J016xJL8a~GI87?gfiLTl1T{O=+GaWL3<-U|JFG?H zOpRs+oVerjFwr^k6NrEU#O35dowO^~`H%!N1D(Rk_iVeK-R9qKIF|Vbg_&GyFWIJF zQ_35!Fvp+~jv0Eejk&Q(38rZjO+H~wdtHV1$%~UQT6(`T*R3#y&`RrYXr-}4enL@SIU~wA*oj4YjGePs zgk-xImKxa^E_w8|f0gk8U2SGc>ag z3Tq?DdFRin(|*Kb`|)gJTYr$N$Q9c}@7rSfN= zCf&t{5IU9E(21M4^`6Jh;?8j2MCC1UL_oeb!->n)NoX?l$_ko$ze+^gRbt3rSDS!g z*3O&K#e&Z_Eca}I_}79P>P;3CQs`~|nTWd^&sDz%_s_ffZqfIPp1L$pMU8E7GOq*m2gWhL-!s^h-SX)$iJrXM_lDF;V@t-wPdmk-dI2y4lq!C zsk?cpM%nW7e7{-x(28mB{~ea$1$%m z?5%wJtVX#q><&3E%{T09-;7=m3K0!HgqwIHFKHkd9{A3OPWB-rVUmDdb9_XL`Ee^4 zciO^bbZ$QM+J36TPz7a1F`BvaEZjsAf;J}gEhJW&7uk&CsbC_?sN3f6_Ckb2+PkuY zxTWE=+9TDj`PJ*6=iP$Gp6C1Kn1F|)uSxj*@=2(if{A~^E~FFqgIH49xHQv-el`}^ zYWSE%UdB!d<}*E^bkSG;4L$z&=y=tIt!2N@_)fit`w$W*`nj#H;qP(YK48qWBf5Lc zooqqOys_hw#rz4o1rVzJb#lW!UFwCux)X9p@b=N6byc^7lx2L6)TyBOHuUPT74U4T zMD{#1(Q)-;R8{(R=3&(Hc0J@^+`H_fuwn6O+Nw!l_%J^+B6niQKO{%l)>|pV-}GY^ z_;drOY58&E!cS%5&w+t3?6A05OYPQQO}0pF!L{38*zS<|R%B>k^<1%hW!SY_^%wtX zw8emOvQ@u~nwm9%0+`<|Yt}DS*Z3M+eP8KB=5V}N=VJ8L>C`2S=tG|!&1kdB|Kaj= znWQIR_l+=A|5G$N=sZX!sbXep=rn)@>Q zyF;S8?c;D(^vIm~l{oLj^M29l>$}mGfaKwZ!`uGdEb_DN!X#is!em+_ev`xOP3 zIr81QpR%DJ_b^6IJpCy+Z(mnwXx=6&4iGzVP_H6bhZ~p0{3S8Ry+3W*jwjxY1iSPH ze!fR2IX1plCj_M6dGKy%f%Knzqxb3`-xkO}xT2h{KlpV?(0+bfr-D>=mwN6Q?e(~d zdN=Cnr(?KWvTQ(r&{}PQ3g9~b)LQ`w27FRuAP~PDUI z)*pJkxqY4*JifOqUkqPubxoxO3^$N4IG>^Ar*iAJy_XM<-*>+)R5O1}S2O)_QEKyC z`fN{}Qoft|c#jaUNv3~)Emj47=!t#^Z~s0+Qi9Vrn|k7wc+HRwglkB+x-ukxrL;qP zsK;4)|L}5XPwTn>C9D@Hkw_eFQF1!QfbdKO1@zD zMh$r^+-&!!m=c8R(9L^EF+1_FO~CWdhVkUcXVcH77r3{*2q8KMrM*v`;Z?tU(8`%O zib%`uXSj1WnNaD1p8V(Sh2`}$eki}+V*p5`Qm&dH5{mdBkLHHk%DY7&&Hpoq=3>D# z7a@|{s-~_CXv&XzG%t5HmH)L_>boh81I*k}In=E8omYA3=KZ{68n!v(59;{&5VnCm z7^8>T1i57Y@|YbL3d(y-8RD_&jUyTY6#Jj;pGPAd6|Sf`_2Qp{5N4uI-ux;3CH?m- zWG~GWTU{%$K8?$Oi1(O+FOXOm>$j7Rk1-PdPd5weU($6pT4xfNT1uwOCy06040Jr% zwd+5v5c7PoYrIo-Ul2W>&Fg+#J<(iI*gD4EYIL6`ZE$|>zB(FR^lXx$ST*a7I|*&$ z?rYLn`W6s(;Ly9L{92&x**g>(wa?T3GrqqGE#FRvgVD${dS-ByGz)k>bg_-QIdo~s zfBD54$L!!cV6XJYVQ4$WuQfpG^P-{j;5*6#w(>C)4p0;h<8oChfOuNvw9( z7$iL%ub|m}jdi^$L+Blm{qFk!`-b+3Uys2-7M~ly21qvuT^yUr>h9VZD?k~^U*{`8&Z6O6sX;+99n2M?m@r;Hrhx( zmPC@*+&dO;=*9RcDi+K7+xw5LU-WjzbzG8tZ+LjgN+gc~ zZ}&;S0rbGjt(}iFjAOXVgEJhZ6WY&j#h+e{2A@>^o{MU_WUVvzMkdP>u^1f%HO<7< zr3?tK5eC<$olWVl(YOY z!2fb}lSqqLli>03vs`Y|ADO7_?HgeuZ@kjN4av^LQ}@ZW#;E8>&Ne)`;*7_JWWw=# zm-Jxj?eChf8a*E3N_E}U*1{5Bs6CPTf=PZiwv4R;ggj2myHb3@S#pSQO&X*|2Vo~fy1TRktS{M%<9wBkU#{09$*)w3Gg+VZj?z?^7f^g;b2WueJV z!Fhn?;;(?4Wk2_I9e6+g7AbVea}k`X4iln!cfGs$@uUvMoNVh#hNa|82cGJmzD3J%YPhe?_(K1pL5*wMJ`hTq`QEe8Hc)D66~fNflx z$D(^B*R-$GtW<(h(>d2{UIciABPTa9|HOSyl>l*?{4CIQeok{TCywP0ISXO#9q6zw zyePdUe;sY}MzffOLs=~13K>WA9trqxEzRS)CY4Cd=A7pz582jcoSs2O8;3Dsfw*)# z3K` z!`r37FXuL2fJ@fVsCIn%ed#H+6B2VrRs^u#M#pAtEg>MSmX*O}k!Vz=QgN+oW9yL0 zvEJjXKd-#-u*jSkVb`#;$Nh=zd{ANKLF9+AyNvpkp_!=cPSC%zi~p+2{sf`Pp#uMU znox2xaxj3eFcB(QYqCdAD^QW=2Cb{s#|DXg?N=a{pWe78bTWGS2ULu9>?uwwJ zs=HY7zE(0Af!Swt6q{7%z{H4-x1PIwd%zOM+!k(rTFiOPHSpz#5vya!+$^i&K;0hP zIlojp&a{V+(Gf$WQ$8zl(j;^TFAqIZhV{QX%o73~Y_`(TtX;^wI= zLx0TNnH8uqI%CSR>nfCX-c1<;xf5tU$%IXUa+X4=?>(!a za2>tD=nTe4FXj$gpT!yqDrMz+QTxLDR0N{O;xv&e6_Ua2Use-2*xwMRq)y#I6+bHx zR9u}psMH;}CV$Z|iXJ4r*{0k48G@J#LNv zZuX8=GrmCWD3%7JFGcmY^0;0+I5_Yj67XbBUeK2R+qHeU$?Ft$V#7#MW!brjWC2>; znXC1PpEGpmlhbW(BD?+KWJn`Bin2Zef5})7Y8L1_Hy*bKCunM58^TR}i1IFR7a58< z7EU~ZLRI)=^85XbqMezI1@G`UTF6Sw5WfqEUCAylLf%P9b2lg`xipy@-3e$yWF3S| z;)$Dd;WXum36H1%ALAwPr#RMBAraObf5wEYA3b~e53)q)<<#ze%dme0up*DWGd8i( zjFdTFUY-+mUSKjr1J+sAb*JCSV$|mzHosS}c43-Hb`v1J6{ILzI=Oeu9s9${YnsZu z9FgL-A%9DIET$e~ zg5K zRrPm*K_$ovCWTH%1HsVd^?JsgWhIKclUA~I%s>>C}V87zofWCBuhR6$jZp{MF1hm|l!5`ZufK29a z%3W@LVe*zBZsbW#df4>M4BT@fQ~zc{;AZd*<6kK;D3!V~n?d zYF6_^5ENau{v>tIHcGf{(T&*!oste?w7`j~ei3uBA+|%Zfi0g~$>6`!g!XKSC!tMX z1WuEN=Blu45|a{!pc%Ki702y@-6uq@4TM~Dz|_tXhgQ8`Jmd+r6Qb^K$*5R-w%ZP{ zKyC!cHV=-aV;GnOd@u#ToO zV;+%a=FAR`MZKl9(0LHRbe!d%7tiPHo9hd_VeSukRhs{ic6JyKWht{psH_+XseN?!zbF!62w_1P zlHrM3n(BH6r?{#D>Q&a7hI~RiW1fZ|9Qb*gFc{oP-zl?bp@X!$w?ZoVLVijoU8Kzk zRH*QCN($Xo23x}#iFo63E}rh!BhJfXd^EY>ISgvU#%ggUZ{6$_H%NP+rC9z3DHZ!N z!MZAzW?;jnSK09ulQ0LVEU3^gyYESqNjUO9P{sKznDTIN(#N7edZ=SiBDOr(LaPVy z#%d~VfKd~)d9_mFQ(_ZD$rO^ktcakXk!BjeGHZvww9S`*Ye5p1 z_c_E%vljjiey3W+!i&S@5ri!$4d;I*e*uAtM>L+z#LPC!0Rr!5VVUR zQv`GIKuB6db7G^1NLOUd(Wjf+JQa$OT&ae5f1pbd(Oi!42x4wlgdJxAAT`Hph+5=G zQpj4`Nzgf3QNTgqj)g$8D02j8wFx~Ce&KvNmPZL60hj2O=N+AG;SjCj{`VfYWtguO z;TgA8VJwG5PI71rm;1+WY*;ZT>YefQFi7)mRL9z@Z?Mk>OpFCWDx`0U?SFI#2@0ru z(mWx9Qp_Y9%*JWym5wpkpml#Gs}l(!pM1D5_5nvmxhyzgA5HeTMsPzdI&Qu8jLo8h zQU6fAP09~k%x3JT(3SCk(R~7?{kf0+eLJbXFC1=5LaQ(wHBB>6(B4&?9dRs@7`AAW zMFp|~dLeTf;L!9$TaiTBvQyKL9|dr;2#%6=DtpmA5cGj6cT!Vk{KbDw+RUV6vMxp; zOlaLB$HUy$g?qz`7~jMi&XQIf4MQE|1-7lG^&L3Z=w`yq(yv96JZWEYb(tb~2ID!^ za5};_jy+S2{g+p;FLgJIjv5lBTDzkWZP3U3!>cNmB|w#E9#dL&7b&K@qg zK^9!YyJwAY-Ik@t?Db|6qv>_swMvE-2_yTwNqM*+ql#oAx!bXuWUsE;cTZsz$8J1K z=3bOWktPBV1KBjBlk0BO4Dgf-e;?Pu#C#9yMdFGaj-zWp_5_Vda+&!S4be z`({)I-2?7Q#zl(}$`J^`VE<&PXP-5WnnHefN%>1a(LU~9NLJf^_r$nuVGI-pMiBsy zlG(W6cEDpMTCU4Ca_(s#8hHxo7k3PbBfS7Rw`5aEG!FDE^<@mCSeQR1M!=C_!64&& z)|Dh)PXZAuy8!%V?FJNC2@ybm38Z=&8#Ev-pI%Z`m|o_NVb4P@*(X>j7^{XjOsHJh zOciu90(bid_7dDVN~f(5i-RbROI%ws7fOxkB5-FM1wiiz^fZCNaG-FG3|m5U^^+of zSLR)98FwvmSt+>KW9k9g- z1N+9pEVI7mEv!3(I!Dz_6Xjei^OGHG#aXky%6~TP?JQ?L(mi>N>*i-| zF{x3tXp0f<3tgp9wa|S*8;X~b=!+b{5~6DB%RucagZ~nQaw|R0y+V2om4%C>2EJ9= zp@&d|sqau7jg10)XUxHx3MQ~CXP!$sXK(N%t0XlMVL{^y7d?JKkt-Tid8P8Lto~Og z8M&FfapfuaDV1afCrrn6h!MVnYV2!Jq)O}SHl?DBIFfq(#IK$W9l2Bi8WaD8XqmbR zn*^6DpUI?A()vPwKP)Uv2XX*EY9TOltI}73=qs^RO*F+-{s}PxYX^eXLN~rimt4Y^vVF-(W z`IvklOz;(eX@SY_mj8VkHFIiH1l*X8cafI|i>l3&>oLs_ zbP`0V{&iX8iBcSu5rafVgc0`Yhnq61JEukSoJ;Kd|}myEs!N2O5I>Cp-420 zF-b0BJ!(Kj>PTkH{=>}TnmsHi3>a&cj7(!rV7J(GN>2Fg_4M!_5Ua%3-GXeX=r+%y z!R+^5OEK(C@e3O;Pl6!Le^pgw;bCu;4r}hdb>@WFw~}P^*0vul_bBQ?aN(l z2nakvz*P{uSt?&SplP_9N=7D|TfuM!>?Xs2lSnK$f|Mm=>Iq>`x)6v8*jq5B{Q=RW z0)YLJoru4DI#}f7e52DZDZJ~Jm3+8fkB+v5p4Kq1E6TF`yE&xupnI4K;-)D=8%!vs zua=fUOe*9wqVk#!J4t-!A@Z0b|I^+4&o-Ng0Fj1yUq#MTi~=P8(YA8h8?n zFOfW22HgisW2dC;L%NlchFO%V`5Y)23%_z4`5paDl@FUfuuy^x39BC$``Chf%$$xe zxP?51nbh?e4fl80roG=YZlXGxc9epW1wx?mdX1W@2GVl5Y--?}D7x=$%sDBbuh4ytXY$m=9qJW@>SltD7I^{x`S7htz z7F+VqM4e1ebR*?NHg+-Mya_;6vn)5Hp%kIp@gT%+c8{W6&LsVz${AvM%SR}esnP^Y zl0w1gD02BMmhf~rR^x`s+rScbkPcE$TIE;GL9I(V?Kj$f&YDOHOS-O`172x&G$b2p2fUbMIjSM<$+;g^i#S5O*Dw-JG48)JT2ruuX z{Z?`8WfksOz^K6fy=|5Gb;UX$ik?3Lxaj_e|;CB}{M=s0V#pM+hdP zRvF?)wB~&vhu4LJxl2of1yXAgBsz_D0EUl|VjBdw!Oj}q5+haCA>g4HUIh-Q6V!w- z_NYIizGTC>FLFO(*UfLEchXsdP@z*#*|knMaPiS%!2R5ZWw8gcW;c6b%Be!7`pS6Y z&XT(YQpYkqpi^Wl2GU+eLwNP!{wCw^7BP9a*qIGjcEU{1>SvY^l#TIv(X=DxnJEtA zVSZ|U1K^P;$zx2S_*l5;M$(nOLshUC8MN{#oH87nfHsNrJT}ED6icXWacE-?sE-da zMLIw+@KrF73pO}?(xAammPj**Om`UdsDI$*6txu7yAbSKJR*HTKM70QFx6h{nO2rI zr`<-xVrY~h5X7Hd;Dd_d{{^YJO6#cTPkhS2?-x@c=y;Bn$w1{1`g9rcZDbi`P+`JyH;WMKCo+JqRH;j2lelm=z8K>e(wzw5;N1W9#iP>g6Au zSW_XGPgHTfm6am<9SPG1qp?0%uaJVeY8)!fdqCHYm-m1b4d>mCmVjN{YfSo;75B~| zQ!&hJMfj9sA7OnJJ&cW%X4M!4%x1Vk>6Xe9jkVr+PKRiJ@AR<#ZjLOel0Wtm^AMyA zt5g@eL|faAzOcUqnoK` z0oxo@IBwb+*t_I=PHd-fu7!F;Ij_?yp0TluS1=V@tU(i{eLZ>YMt&>o)*6IrDX9Xx z<3UzgtdSEEyI{B2NuXuIY%%%MmV3S*0hI#WjTv8R0=!i!X3VMAx{DZB4gutlEqbQ@ zXhL24Qz*>*D>W;6IhGV`qcdz8GY9GyU3Lip?e1?cvwpn^N|i-4rGSHRWDz~0o6|pz zgTR=N&m)C0;ZuE(JE@G@MG?+V_99dQ8eb@#{8^<+jk$!aP>7kE`pQ)% zh16!(qkHk$ye;RWKLb_2RpJu^a_9pIUt-;5Q%Ct20@FpHW@H*Q52D=Q!iV;qE*wed zz5(EWI#=t)7kIH?5Jw?4?!WUqg&B`|X=s`v-l`sjBbb6|6cd%;-R-g^lAM9};ue!U zg-G98Su5q0gpp=?RM?=K^n5%Lk)|qVX{bA zb#H?x;DK96=Iv9w=mVHHB$voOmJ`&0%6-Wb{pf6V1_|IkWHeE<*1<1;va{gn57dC0%KLsRoC^AJo$I_8tINEC&2gzn+jyx>; z8@*9ByK1=1L%T&m8{Fy`{9+N_zFnrG1xD;{d>_rd zOLe}BL@CzbEd?noM@O{FtU&qQ{8Fb9hfxR*N(-Jrzbu3Lkcfe8Y3}>I+9@h+I=~ds zV!YRhbBW)a6<+6AN*NVa=EO6Af;F@-M!lSIBph3ux#aKHTiIsrG4DJ{{itW^+)-UA zYx!iYICSxmxgvx?QR-;TdhaRNRm1!XCkiZz)^Qh{BS{#XodY>+csBYr^-=RRG0+`4 zu;dvPeys-%roYX!f}?^t0qJJmVzm=oIkB8F0i&9u)L{z?BXhTjg@|A)N&*{N?XllRXD9A zlyUT1h6)FNlxfgvJVa=E-GQ#wW_dWu0~>xa6gn80txP?wLNq&dvt#v zZ*pzzK$BHxfbmM>?MMvwH5*6tCH-V-Q7vZb%cWc5$(I6AkK>9#?l@osJaBwaYz^B6 zH9m?3neIBaKW;WgB$KYilp--?uX$t{JA<-Al7~^+y4vTi*h+%JI1tf)J{&2h55B<` zF`|S07GIZYC(8Th6}n$oSO>}Kmr0Ii97!14`@~u#eFN#8Kr$J9eDI?ZI88skv|G-Z zR`(5|ybeOxw zN7}0T1u0?b3!_1`7mugFNuyKJIM|95E3?e`X)KBtMNry<^SgQ{ofFca@=BU8b-;1g z^7v##-Lz=XZI=H?;tOjdIZhCB#zdcATNzVsdoSx^O&-jgbCHXQ^gb1R(@&Lax+3Rp zPc-R0c}7>KD{czv?$Q0n+LB*U6ku-paR1*I1Rnt282yb@|*E(x5NZ@>$C=8{K zv3CTD>7uBNbD;8vNzpKY>V}uNlCM~q7Gbyp`StcNFgq`&}q2eY`W>1I&@O}&86C>%pN;F z`O9r0q-4WqA#%Lrlx(LwtXxh>B)BR4p$~sZEvqKJ^{78lQC20845720*;KGsV_Sw9+g77Y?gR8wX+A68DoYXyfh zQR3ewa|zUT>SY8P(YRLtVnDo`{|a0cf1o`~g~y5@@Oa+1&I3vh?MJ?+7-;hy-e8*0 zF*Ov@A2)Z7ssF(D+M?Mq?8g**lSdzyNH5D{t3cx&(m64b4MGGX^*#rJ)A}+e77g)I zgUI*05dZJ(z0YszAwMW;E?u3Cb%#fX_gDy_a$$~6W6OCok9LSBAB>IM=H4HOgKD*O zrhWa)>YhdwMuqs9pg&yA`HiD;@%L6ArEhTZa3jQ1Vpv=#TqxZ7^~qfV(P$Z~V1HxW zpwRCoQ#hI`!JVL&Q!&LA7_wxDt+|k`?tI7u^xAC84xlr+EhUdB^$g;1YeH*xLEsj4jPVsz+zjeC_cK z^+myEX2HFJj9QTdolEcU%w&*gV5$y{gdrAqxOYts-xR0%JZMo&T9lan7gSUyS@IHw z;_n<)lPYbfm|2MGc=(U>zgX-$1HNd3h12R}fb1A7WX@lgmuPR*+;@a|!$P+?Ht!6I zRyL$FCFidwIEli=ca+))k*U!T z1+GTb4t{Ek=jWZnF^Mw{sWloS%-A#TzcNQ89`|}F+C(BffMAdDwP3-4Dn+i#-n8_w z@FjoaM-6PD2j9|2M2f2x9n7{u?qK!t;m|l^jZo@S{=MZ&jK3U|b?2x|pDzuxaL*Ui zY9zw0ZiAd^d0v1EXAtTADT-aA?XIu}!nGf5tUm@!%pDJjp#opG)O}%Lb&LPBmp=vxb?omn3+<~)$p9Da3-{&Ky0Mt!s=6KCG`W%}M@0i?>nxaCzJ`aLp{lao z29UCl^f#i)TQkx6$co+x&?qCByY*(l!bbFfkY_xL%ruc_s=9%z7q&2Fj%)b?W)o@X zCeI>~OEy&5V_+{W{?xx8G$1QeTkK}?j6*CKeME>>MujP;o8}bM%XHR1Jv4#n--&T+ zkeOBRLdUOpAP|BA-xPImRf!Op7e-9tQ~Dh9ejb zyS?Wnck)ir#5iw(vHOX)`hcYf zw&){+Xbx90uh&f^LlLD5m6ZEchv-2DfFr0tJTi!PgB}&bQHM`ofZm!;CYPS}1U(j1Dp(r56`oy6h{SL~lqEsGCZiMAtov zUYKz<5>)Q5-D?jQ7vlD-%%V5#S-kKi5_}{HBSA*X!(At{ZRpADESsZb4& z!2xsI53?OtpE@K(>B&I>PhmLw2WyF8T~BEWC7yw@nn2a(A$Rokj#MyO^!M6JA@F@Q zv??M}VH$DowZ1NqHZ4zbb2gqo^$paWC}g&6Xkdjblo&n!VJ8#It0Wn|S3E-~^k3m# z3pZ?=FhljMUJ8X-IOub<1i(rEkL2#)KQYo8Vx8FqX*R@0?vc15vKQ@ZUO#X=nSpB# zsDfdpv!aTcibkQk3AHBZ&P;Bt7FiUud zC9yg4FJU2TS;C=(B3!%9khjfeb);}_53b|U9`(_SpjA%#T9bCpi2x)eSb--M)@Gr* zZ8Th3_%M1ACY~sU8uYr$Zvo&ZZS*$`Gyc%w=DOZ-M(#w9FdqzCxahnptN48rI|^^Z zz zP~)r>S>n|de;6W4@fr`u){C(~4^eq@)Ayo{ zWW1;+6cbkWm@AmExv+gY3*=?)!;IN1ul>{3fAu9mx8zREJ4{&#i7ED8=9Hnl7As@t z?&W14hpIa~70zt_XuxN{jppf-liu>nF{i-sy%DN8?eQQr8rf zPXnGK%TXIqtzDoXEJ17*9dz?%v2TJIEoNihh0!;xL+1w4KfP$cBX$v&MW89!Ok#!n zyH@8j{g9vs?m<~U+j(U%ADY7|Yq^CG50#bDO#CL`SelXT<`V57mX#5faFKvJ65;O$ zF!gYKpYJ{a@D6*_j7l_UZx*fAUZE@JVwsCsjLa28QEr42d?@lHSa z*MvLC8)Io&kOs}XH-+V(sreg!D0m5*z_dSym2xB_1l^r0GQs4OmqILe7|6@~Co8&) z5F}oPF}CoIJQ&-$Fq=##W$Z+0gMq20WD6im6n;x>?hFFb<~RNzPIAFlG73zL5iUEst0f~>&= zoeE`W4^=#YV2*_gla>x0)()jOL5@wNQ2v$cT!n+}7EU&Mn&#EaQ$>nw^GO=kJ7331 zdeP5a%^rt5I*7y4WLz3o6sQU#(|C9hFu?REblN*NCup2&ZK}9;dI5&-)4-&+Q$#2& zEs^QRuxeGYl5i$$pB$)0sxU5m8}TmwWau56@5CRIWq}wmr*%?Elj?$7uQ6{^4G^|7 zqWQ(JRRp$cadwRBPtIKH*s)ggDQqN58UE-N4)J)#4Y%B*R+E-W;kfX?CQp>W+BT^D zEsrarw1mAb+aG%~u`}q@`(6hn;ERYT1YMpbH%8VTkSFIIBQHd^?0Q@$W-xuoW%hnP z2=6LkwZ$N%oOmY4nGCk~&6b2zl)x9rcRGibdTc~+vO zl%HE>4QaT`723b|y16X(Iy+~?P(~H(B^2#&2RbN})Et7n_~3sbgz*z)G3bl)IPgW8 z6ivZC8Gn`S@1g%9z0liNHmOyWq*dB+x~Z=ypPd48r9wy_roJvCi#=zK6U-i3!|GFX zbu-4Y|55L2`SKr5>b2nW)~x08Amb&1E;D4+s(U&8Bmb05EdQ%@v2bt$v;7-Z1v9H!xH^7w zF|%+5bNp{X%+bN^-?%IIKOo`12?`eG)+VBko?tzee**UxRxm3o8;b!vv#O)pKdSJb z_KzX_@09=9;(ypfWfw;?H48Ve-oL!!l3-?a3r{z&0hn3L(azCD&B?^f0{kCDQOuPU z{N=wg2@3uL75^pwFIiok70me`8J<~Poej+OUo-xN>|pNy2|2(#|FiD@I$-^e$^WsS z`0otNBL6`k9sc8#S=_?i+RQ>#O7#CgkZhc+Z2x~u^8W=R^U^)k)mE`1X1ch#X3@#O zl=t}FaNv19X)KURluV#9Fg%pXT^vdh6OC5WT)h`UDuT>R0uv!5*mN207FBt;Peokf zU?bKR?yC07-DdXth|bpPQOokG<(1!ZJ3#p@7}W2k4H3vuq>Xub)~An-F){cA#6^Wb z)`sZa`T7+k^(+oteCra(%BqweZhE|A3N-InXXsI;a{c`okVM8MMga|gmssND_ou=+ z0H&%n4dJnUg2wODXxYM9*|3Y?ifhRB2J7t}D-P*9#xgUg_KWa!rtvyC@?$%cH?t{s zN@77p`k9p5mL@Do&_hc-Z5PQ zf>Osm%PQ%jmhj?2=l7x2OV8>SvA^28z^M1D#tqf^Ouk5LzRs52c@1+HHsFy$H;1UH zJ52-d(;iy*V5dgu3Jkb~0{q;}y(12{GfW=bMWjZEIX|~^g($FPqCe((EeLiT?+NF5 z%9^-*)#NM35eg!g!D6?NI4G|umlL0yL`2S*F@JwT{oL#2v7QImZx(oSSDhYt-{+6lnrq=v!s&$Gp}`ep?13*%94m4O*`6aa{kLsB>hc?12< z^iWyhN4q<%YLn_+6WF{zj{cG$=tn#3$cvDv9X=u^n7dFGGvJkMh1&H2(Gy|Z3gJ0| zm{@=e#z=&L>`suIU_fY~G%92|B$G7IS{T$QBDey87hzq2a1XI@0xSl3&w><#Ih~;O zL0Y{?P6&vBQo``zeR3=in?csF!Plr*#UfRS*rh00qQ6lIbYZ>3M3lKPA&11G5>b-ESb`gI(L`+u2sBdLB(hTAcZuvo z|wmU2%Xp+Q%#fKrm`$cnP!=q@;HZ_Us2hEUV_U^mwuFM zQ`ZQ&!*QbJ#4!$P8YdX*HDvsNTroN4BSaqQ#oHxx@^8h}XLI;c2WmlCj_n9M8$jBj zy7BC!+r+#IM(K0CHuWX#h7TYNAl^zK8SbG@gwqAt2BVOsgDLDN)KT$ak6_3OR zHdLykC;%H#q9h9`r_xYiD#;Q`h^{K~$hHZ4344i^sUlT6ENWL}w&&?8b&31Q`Y}tT zuxH$5?2Xl?R43V{on`n?Dy1%Gcw`tc6;Kq5%O&^^g<*FBsCrG?%B%>m&7{z22YDs(@K@iV(BURi8PY)5Ru9miqY%-+m8XT7!I zXD4mi3!MX*o1!E44bA~}7PMbSk)Cix~MJ7(lnN!4?7CAuYi!`x=S zoTG09_w=Y5qVi;tW#YyZ)K(TZ)s5R{e$F7;9$HaxRDbChDQ@_qqf;aKyO3vqf7G|c zE9ZqCK_EsuCJ%c9+lb+UL5=Z@fkcN^2TI%i=V`;=fwjSGTLUw{k#L(mv!?0tjl<^J z?~GgSJr{m_*#-?8*d2-;GmprRWUo}OtS|x*o)KNhPb+TjG##OSOK4}uJFU|L<6k9uDDDL95qzuUacCQ{+=EnMpFrKvB3`Mgwgp?shBuyIcyKf zF{vSmB`F07ABhYJxeRRvou+-sSlw7~xd1i^0hSMiyUX{d`3<>QX5YMh`*$}s;(v8isJc2U zt8RC7MCQpn)u9*a_j=EfALD!~eI^9sy43@9L`y}{M7Kbt_-fYeDm5=Xw+o^pqO&Lf z1rr4$Mn2W|)l>W=+Ck-1>HsdX7P>B`EP8>)L8F;d1(ZzQiOBEdHY)l}@nNsuZ$v`A zB$0Tlz*HGmt{MpIr47mqBkf*qCvKY$;SO94Jh?OLGdtKBwA#P=J$Epln!uO%&X%ez zHAp(BcQkI?v>t_<5txZAoDT^Nh3es~nFp;-%cRScw`v(yo$dDWH}K1Bw9t&I!khM( zqM4qo=vS2(FU1jQOx*k&+6>y1B3X_)T2paTdRQ60^*L$Dxy^ZUSht6CSYA13yi!j1 zsiLtkUJA5fcZM%BFYB6=j$0MARjsrTjKX!ps~PhvTg1wYg=g{(vkyJ7!xMK~4qfU_ zQWpD`=GxZGJf=Q`g7rXf(O4`DDE0N$~mu z3UVtvAbUx>tsVan^dn<-c{Z>%o5jfGyUW_auc;K=QCu3Hq&L^=klTdBszC$svB*)h zCLjtBGO>OzMQM}gP#Y_~XxjQ_y82lXQ zJ~x>-O5hP&&2MFYoV_*M)7{^maxgl}%?nyBYUR20e93syx$cWRIF`DXib)IQad3rt zzH}rt)8AdY^SOHZcWeCJ#(lR-f#$HNfB?U?jh-&SAI7RIf%;$O^Sep@m+ksbi{0iw z+u-juD=RzWAGWj|&|YRBpc6OJwE*P|rrk+Q`z@!WtSl^FN%5Z|1HveY}P>GGLfFZCq0BDrj!27`j_^bBUwg3JW}8dhc&0vZ4_fPeu2eBcZW^i06FNEG-! z80qkt8<@U(vvhnmI`955JMbw1J;pyzXn^Yt=&Nd5is%^`7}`R!0hb4zoUNXj;(HI} zKU)b{7=iw#gtp@!s}#7w4seJ+1_y4#qsIsw5-2PC_jmK}TlM_8D-Y1Qre|em`49h; zg@u(JsN=ub#^>+;>B3&}}8tz6+|r z?ZrscB`2mcCK}PHY7!bV<5-p*2663Qv6aWLuvJQMH06l>AXQWLzkKx^5@@NLXgJ1I z#9&}kPSJ_Z&X%dzMe&>3)2PDF9!A;M*!NsK)*2=cI7_I4$0xE5p9J~zig<%M< zm&6^CW3Rc7c-wT|0>OlDS|doZmtEHT7has#n8gC>j@HG@RnC6%q@QpHd}xts8V85R z<8l)^Q@T{-vUV+CJ9GW?@{rX4=(!q@8jlOx2`k;dH){?|W^-RMYFTr}SbUO7{z0)h zh5GoGJ+^Y5{fk&P0#k%U`~HYzY2b;$zF;{RuLqydZyra=zV&ND#a)}^#|^#KNBpH6 ztdfa1Dgcmr5Kdacgnwt(xEg?h+S6;J|-3u(^shi*u5X1}=r* z_<~INQ6Vo;zZTgk6_tK1QzV})$}IwBp}8WE23Sv}u@FXdxc<^emMj?Tk=Ibh8)m&) zT}wP8nNC+zOY9=R`o5JVufdeYVlaZTE0G%@!x%rf*!q2LH4mFR!a(=D(n{rvw>PWx zeO@Pfl=pQVKp8X+7f0De{r3jk)+1yZ#VAcA38PT2aw?)enJ!InNps~b$FAyA$|_i| zUGiLf3)3jutjU?z-Qh?Rl%7Q&G0%@9eb)8Jw9;>DP~kg9ppIAP2yH?u9+TYbBXRrE zqJpvmrPIU;ZD=Hd<}d560GVrGF8ZL?X2DESASZ_@JIO72 zvLkKrm1f88c)4=XE90k>EXTboL|^mQm?+*6V@cT(xdLjTFWd$@(yacCRjt&=-FcIi zUulYTDQlu6g%t>i;6w`v}ncbcs<`8NT{Khq>X zcogOy17X(c2Zn@b#Tcv4X|eKpEWYgc1|^Q}^2|c=a*WTY zoN~XT14@%42(8#7tjl!aEr$v~BQyCXT ztjQ;KHRD=HtgC2?A8DCjk)zf*sNhNl*-J4bG`jor3dOh)RWgwmBW=7Nk!l@OO2Nya zgXdJ5tYolQfd*Oh2qo_V_d=TamGI1^NNNS49Xl(g0u_-KZ`5?MlOfPoiHGtDN#M74e~;5(!9I9c_HG3dy4Kns4|=n@fVWKdmYX zUxKgB3SJ7W&I(-;S-3?u2iDm|HYe2GL^k`@l^}`m#Whjt6Kbm%D;*FyMC32pcV#=c zU1oD*wQ5&7xdC6<1w=w)r~9$>GNfnbU$juq7qbYjj!Pe39jUx|R>9lxExgym>qdZu z@Vsvc9auyJ59gN2usxM=RVbiV^c!fl#|x3ni%yW3u@$qwM;pn}H~eK4&@3Kez6Xo7A$1%)Rv5-`AqK{nK7shxkL?;&`euFYjpu4}KN=&Ngv zRS`mB!`;5X1lq1Tx6O;**~FQAbTh!Fjrp80A=%-6W(f(ofi(Av`~wN5wu%U%MaD;t z-Ey{kBu}y^bcC3>F)t%i$^kymPrbXDpSRru46h!ejfJWsvbCLj@CR$=G!v)dDa7K3 za~5;lv(+SldnHvI*r5gRUDxUub2S|ex-|9Z?PTWiTF9@+ewFy`E~B8L0ook16Xgtn zNWR#B>OV86Ydq*5O>vXAbagTf2eINjbsS=Gn5(jryD+(kbLVmtWQJ73>PpOSBy-R% zD0l)>)_Gm;R??ZX7Ro|it!@SpC>p9~-b#{USrxsZbaDB}VYeQotips8H;QaBsi!Fq3!v{_K znj-b{y$J`bwXl=?rJP<*0J@CJc!*5{9AEn+{iU&}EDDl&=ONq2CgMv}LT?b#57O|* zA)Mc8A}K%?`(<29 zYX6rIhCjS9uo3~Rn9uBQj%$a~!sAW=D>D6#Q;neEMqG9vD1CO8RP88g`=2Eg#yJ9+ zpd+@DC;7r`lKi^J*hY=0SDRapPJT$KTKU6YqMc3fg}H-2na&Fx*n9d~>GY>F@J6-3c| z;?6}Hg1z$_PzS;{T28msvmfeW%Xjj3WQJI2%2b3)_KMqTtrBqh8#?n;vNF&gnfPXL zL>qpZnUpdGgNwo9Y9F3+gt+^sIdPd!_;@rFu;ZPbhB+_~NsyMz&EVQxs&IqFGoz#L zS9ID`?@3cH8rA(cx!C>D&^l;Z9b;jRykg#j`{uXEN{2mW+wx#?OGSddrW>?4IAmty z)i#4)4z;5g*K}UJq;YT|zqnFQ5`12d*DS@*(Mcp$6oZY43wGj&D|n02Te&6VDU+Cm zQZ5J>{|@gjP_5wmLf9s1-=o$M&+9R-aPOvct2y?ZZMhc?@38?x?P0c;bWL#IyTpUu zb-GjDD>PYl9dq;q_({*$6(sV>la`1|w@+f)@JleFYS?#q1qFF|W<}=dC(35D)Cf(M zElyCrdp+S|ITWRSl%we{JJYF^WI`Uvl+Cv{WM?jKj&}&~w`cLGDxzn2UlTGG0t+mv zo=@f9qEALJSbCn8%3hjn9LwL@)(f~CiRJrB+XWhi1b$iqfL{ zfCf)(l2?IFpdy;#Nl<3OR>Tuv(FW-!Xf#^ybhI^ATM6F|^V;JK@jRYbxO(l7mA*WO zh2ytyRfD%$VY?yaE%bwvcyXhUZ=ETG1`}2PBL37-E&}V9>X31aPpkFZVoZi0c z=B(^HyWrS|sqH+XYx|A^eW(3|L8g(Q^)Pw*_G^VETfqq20u=NOS~uV7gH2`*5YX?u zLo=J%i0>*pJ66u^Gxgh2`ZD@`RQ~)-yLw_hV4Ty3UzO z+qgD?2I%s>5r)1x%g$|Ef_o>sZ~6|_kJ{$kbni$H%h=Kxo(v58t*&diaIPe&B=0v& z-BxuusJWUxW*FI%U@lHeFF9~O?SqA`t;y6k?MLCF zI#s3oZ2+WrhvOHeXfSdyJr)7tJ#{vbv^8tp!ZF)+H`l;{WfN7X)-oN;2q7Q(GN~s= z2~}@vm9&`wzNklLvvKR$s<6_UxJzsG*$+>sJs!Dx?ja1*Yr7TMc}U61-{3t4z9d9! z`yU0;o2Ud}(Qs;;VQrh%GCMHZQVfSpQ z^`(`|<-FPB?)g&e@krA^NgtobZu6ocp-&3$?YeXzI1bP0m$Q+=#Fp3kaFFRjhTu0J z4!lc6ttZoo{3Ag*{}FHu%Y|fk4ojM_Ur@#y6_6TxADVjZ!CLX3f)P?zemglEkEI@{ zk56r=O5rtu^S$OUa>SB1*XLe5V?JRz-V&hq#z=l}4O=JQ4~=ZnE@J|N0eSP1-b{;d z)|5a)cTDsqf`>;vsl(L&N@%kk2C|88FZ|`_>O-yPD=|zHoh248vfOW9DmBEbAwrKA z`DVRGIWyzpd=ftq4oWCUY7`Y5%rPeqDVGg*~=-T->4#z6^~dXLFBv5W!`FElSQjLYV)kentIK)y`9aAEjPP&tUv93Ay z^pZ>*>@p*eEIGVDjPsRk2Fo!tsRbJAzTekshAT$)^Nhld7azU1EQ_MPj_I_68|;E2 zzW7o9%yKhextW~|9Bfb>5;1I7?$A7bGm3ij$UR6S} z2#p4dHGxx_=ViGh#iefaRwWnX5&h6FdZf#0ES7ZF<+^kDA!9@0*r2wvO#(eJ79MYO z__ws>)uwE#Xui(_E$v5B$`7gm9iwnc``Dv$j18Y5LgS7 zJWOqF%`Vb9lebIj-kpOr+k@1GCjW*s_+MeH1Uq8e$;F%H#4Yve{ehr3 zU2}e>@^N}Gr1aMaChQUzB>b6D7wT!A_tuNH11^(d?A97BS*0Z8CI#VNww-PDO0 z4!7Tcw4KD7&FMRVOpPeHVp>Y<71X-s3ac7$bTy02Ov7QsEUUHpU$DIEV?NXuoDn*S zY@zK0LKp2z22;>&@J>+t4BWH;Lx&(dsp9>+bG}peW=R)z%d(p=-xim<@8FNmHxqEj zfR6FoNPapudtF=0+Ge7GqK(8FdVqjf%NJ4Z()mn9p%L5SxWx1;p@_v`IyahoBD9Gg zOhMpVE9BkefGIFVW_9 z`p2SbCbC zBqv#me=gB*#Fgl4eyeAnsMS%#JB{=zot@RP(X6lSQs6=k9y3d4iM!gab-b%BajO$} z64||;J4TzXmB}fY^qc1IJ4XAC`6(S^!C(9nO!UDQ__*WA-!Nt5^%H@lAe^1!QWA7N zs;V)KzP_F?Tg%P|#4;4o;ikDH^RluSXd1xGOZV$>t6v{Q{; zFMr*?xnplW950cn#Y7v5BTaVxV<>OBGc%S6ABkZ|@Z$XOOKTa#x6tg2fequ%w4U89 zJ?J=18P^;Z#hiwZ<`mRC4fN=T=4zNG2jMcD_CZ0{d$>4Q~rZSeSmLvhdxbAzC@nTowA}?+`bTEB8jqKjNu*Sr6xZ75ywQ5 zr55fmO@{!Bwi7v_be%nsB$M?uj1 zl$>bh1|*0>($Z*WQb!D7O|oQa-tPBmXC+JFYcnoK^8y%j-2JZjtq`K(E+JfR%U5F? z-LOQyIAn`fgq-At5rF*K044ICZ;;ba{sTL3Mu@vUReG!n8RupTq zinH}8Y+0Rd0xJusm+Q5CzFQwlmRTJe-Sp2QbL96rCFNeeGd-n7$ex@c(68k@ojw}A zC9&M%6Vq()uQ%*1f%(=5dC2%1Fg+^S$_@>FuZQStjzo~=kIq24CS*}8#!Ds$(~AJd znz{}g3Xz>M&=ly(rF1sx8!*tucuT&KoohAVTx^lT*_s4F>;vO~n0#?7 zk}2kWru{s^uX;`@dA_g~RuOZA^elobJno zI%lXaO+~{^1fj(DOADyRGJSrTRvII+EGP?r9D-G-TZy)o2w}b`B$^#pvPG@a{Lydz zx7*I}gYR(49y%ig0=3@5=(UM2pFW*ww#V3;m6sjOclI2#=Th}txuDKe2=ftRzTznv zn)OmG)NgWzzitetdkqb?F2H6>J+<_7+}9u!0iB)NOZhnzcs-};*Bq_}Uw(NA>*tdW zK_7nn$v;h+lbHKKK8aD^nDIp5p>NGPa4}E~=ZB1(Kf9?G5yYzY4}{&B>>vzgcqLwh z-9`wf^TTgV(}ua;mwxc;PpPFN7wC)4=g*zX%g>-LGY9g2t;RZF(28NDd;z@Yv zQk7|Z=w?AJnajp}exBu6G+P(YIrCHL&iKf1Z^nDJkCov>{IYT}6uQtiKF)>w3~~r= zmlfVw9Av@>uG4qrZmX~KOZz;y9_yZ^OD_Ob?u&tv{*tMH9;amz9MSmhf%Hn6RkY%Y zI29Vw3CeQoW_=wUH0clF&egU%{=30S?xIB5RRYlBW}Hb4>9(xM-u7c9n{*3o>_>AR zE!BZWXCR1(523+mRLQA`>ZxYY!#ENoYM`2fVstqW$dFv)1<@s z3cD_!XX?__u8ol<{fN2JoVYj2NZR`xUbJ)!@F@;d4v_b4?~j zvjS+eKH?*-5k{Cj|As`s{~D7tg4;y%waR+^mbgJK{uO@~&|~-SA?Wug<^L_REAY?A zF29AT?w?VuzlU}Ikvsa&AnyM}J2WoCU3*}jKs-)}Ax{rhYqf%w1Y z#{L;T{~v;y|9;c|%ZMg0Bn^ycGW`|NWM}yQF{1fb;_hDw3=Dr|IlO1~{uR+=W&T@0 z6BwUo{htGxDJm|es&h^}d&@)qU*u3l1D(ffY3&}QyTw&zIck5(Ws?s?>4;aNMp{uv z#%>Eg2M|*PUK#$}V^)%^G&icN{`S(hOAQta=WidHvr^vBu5XGdeH{*mS^EJesAQgp z4_nu)oFMY{>6Ao|BDSg))v@g?`HW-F_3Z52*y*C+Q*EgFPiXPslp#&6-MmA(52wRi zEyXH26TO%g99A3K>?XzAm^KemscyGE%(u@BI%sVU#)Lc;p$mJzR`TezL!HR9_NN24m`O${j>FYb^7QE2VKoRSwRe5|-8!dUb=s;)|Lwsd@vTqMtkZ|gz0l+J z;*fbM{t<6$xZ~r2ymrqX=PuVSNwW?51HjRu6 zn&{0fFZL&9XD5S#4`zL4$FktB*oewMr_w~F=XnXc%R&rvH^p+(hY?VTm>x5(khhFC z2baH)F7TqK3C^JHRRZ=n_m{WmO%o62XD>f!x=0jSpnt@vH%h9j^7NFTd`&r z8NXGE^(?phbVui{d6tmnyaE`?tlLDXbL6?#M@0P~*O+!io1-!uy&W+;{v~NJyDHHy zBL6df%q?-azODf;i-8SUbxc7B>P9mffz9IuFFm=6Vr4Y9C74XiAjwt~j_goMfVj5d zRbn$2=}dnXYoe1AC0AVRtt}~ejHUgiA!$AY7!{U8Sg1B-B%EPoT=}Z0B9-#;gVRDt z!KTP>GeHaD(Ip)$xXI#eW)<$(0c|1TAMDyIK6ZPc?A@Zgm&zN(wPD8L>DY1toVycYKQf#F_F9BI8|35?yp~d;IMbp} zF?*3?OdfcOL62 zt@L?*>UI74JvqvB4Q{jn3y#|xEnY-QKU-DG*hs~5ooWurQk2Gj%fg8>S)me`(5-a7 zsB?K#!HY6154Yl4QD4jeot%zuPpWK!it1%2#7ClRfol2@C&Vj7tDT$;(wr4q(u*U6 zAFBfbR=K0Hsd`UKTiqn)8Iwdrt=5#_aV}8mNB2DVPu-MyLnH_6?~Om(Jl#XbEy%Vf z)A2h9u8HSAzCa$1higGTBEbsqcp>cz(?h>NvH+`o88-eyl;?x>y2&XN^xt6sSS-NNwbqkhc<&_~okGC6HvWD@7@@C8u?hgMZ)f zWz#P=vg6BeIu0M=5XB_T)@TH}kwBkS=W4;R$7sRNgNp-Y|b<^5;LN0=p z7N0Uj|3}+?;b-*^t;N;@El<+qKL&!lD=A~JVAA!B-4IAKfcEGD<4Zh;qNjP`HY7XOvGzDwXsD z#6v$!<5nXE*#Sm9ZV2!eDYM;w*OS1=1s+bhfOWtjArGVLeb1`B?G>}f1a8Qu9MLQo zOKx0QdW{%eT7mp|4sN@$Ou?Qg&HoJG0kU*qoOTR47C`6%A~axbgsF@ps7a%8n9fH? zEv!B7ABuCI@o^gwQL%AYYEyoZY6p?ZDr}7p zDW$yco{rJK-%W~w$rZ=~9qout6YUuL9ghfcj1m1zeeH(AMz_>)k>98XfG&27Q8A`r zGGss#jhR{{{nHVz+3o15MJsIhrBy$p`!&-S`AJ-P!QjMUfIo1f(igdFXx+`wtxah- zvSFZ*J>u%X${_0qu z{e_ymw9?%Qr93<)5Yc4)ZImfeTYCa_e(W|-yPcvo{0+X94nTOnXwcapbcTtj?8w;M zQC@`r!px$c%#hc%DRYCyLV1Z(Hu-X}gj|kgc7agM*#WHK{-Q;qmD?atwLBhI{&niJCs7GRp=^(wKFy z4r$*_$~%R!)k1rvnQ8fkBJBqP_oTZ34(fJ1iTY0lL8={9K`^BuA%pkIql;IquE?AzNtf9 zbF0g|^t@5ffkvM$F%s0*ERhCE6ZZrf708#>!5?sYOn0|df;d({CQ*2_h?GjYwXysGm9qt;UszE<>gGGb(z^USg&6(&=k zSvRwWMa?5J)u`4Vt*Zfy++2+XyKJYz7M-%TCLM}2 z<t=}@i#&5vxIBx~s21kqbxH?h@HeH*CPFzRGSCZC2CtAt2KCL#NN-9U z9GoPatjKb_ps$pNI)s4Qtn4p4hW-hy_QI$cE2m`z6?e91Td8k(eHhCvV^dDI=fgP$ zO-V~QLYW!2Qx`pb9_4_=6}07xPWwJlh42tA7RDFl6WW!NuRBGl2@e;kVF@BtxdNnS zC&aIGMB=lz-4Df}Y-M?PXk&Ex05bru!zU^6PeJi|?`i_g!QE(n)*+Io@$}vPTm=e(nON-Q#zr+^`VO8BO zUxR6vRG9CVE@uXvS=sF%#XxiA*GU-FOo(p%aYT?Gss?m4q|)#s!|pyJt=`R8iko`< z=`Fr$b93chXGTt38x<*jz!G%YbWWqm5hL-L8g?7!W2pGW-s5CIzFYp+Xbz3qWO4_a z(&#Ln-`m?5_}lXOX7q)OtU>nPR>pTEU_75C$=l9Wte$_V_Ppz+H<(kl|T>*uE( zboXBnEyG(EhuoK7VkN?N@h|Y@S+R>92ngy$Wfp+a5_u-vRT}=^5K5Zsc}X}^MQg~d zFC!zUD!Lc?A}9Q$riE|%HQ%=14rgkSxmqe)D@zxHS8B~lYxP|gkL2j!62o^c3Jw?^qe7l$69sW}i}|nL+%p$@&@?pt_Z<=^G&M-)BlLE@ zDhG@$N=rR_K1AyAsE|?KXv0vh8US0Ug5!vs595`%6in~~3goLb=(nMtax&GG zP-%VMZ^a)u;a-gcwoBnTD4!Mc1U`Q=89(g5U;TMec;Rr4kAK!r(rd5TbZGk7#K_nP z>iE)F`Yx$VLXCU;Dp1(9nH5`OQJwNuVKNd#@>*-i-`d7bS%k=QYL*NIfvWTK z<0mJ!2wop3JvT+Hfgd3ngUyE00vLU$^`MpJz&&i@vzq+YVWJ0X4~S-tvGp4J_AXdt zp#3KhttO_LzBW1=fBoF(M0U8LW)BADll;5Ml{_vkI*7C{Zb^|U=HPJ%1vW9jx=U^{&h zo=0^r(ZyN`U_Zo+?(7>ayvR!AE|_0G=y{HOe#mjW46M2edBG>%h%WngnC~64`oF<^ zg8zj1{>+L0ccAYNPBsDE{{iS@1cGCK<8Lst{|)G41t!k_6R2ZkVjy^jiT>I0Kh&U^ znVEr%4R#=_;!pMm3o8?lQSm2S_a{?=1qjr=Yk6mIFtYtj{$p1Ejm-a~0DSYtvKO+UuFj-e{^OS)`1zDTV;m`#+n`PhZW>{jP`54#37GsTU{Jvs_yXtE%osBrxz>vbG{j)cMS zN9LL@6*y7FXGmeDNs7w-pyS{A&44M!FO7a#hfSMJ3v=oYQX>~$sjqK1l}bWMP06@S zzK^mLvrG#EaE}{LP;vBHfC7p&=5o;UVnkxkkb*JWd*#0R6m;OuZ&wjq1VJy-3%Ktt z#*otRVm2yKB%)EePJ&u+ggw6+FMT&vht*xhk36@q$I6u9W;M1RXP(YqWLIdE zS0(aYS@9qE7&@7_?RYM&8Ll;4sin5oRRw{cQG0RcbMUgLpibl0l_7*V2n-=7`cil| zM(+2}Q$4w-2%2!rU}ZyCLa!+a6QOXBzqBPIB18yf^vt*khz#{drKI|Kt1O~jSx-u- zBpWo^=E%-Vg^W^!5~NLZBJ)vG-<;wklJj(=IzL+$Ge~bald-+P^SjWn$#MfT$*&Aq zDfz|+SJu7eD6!xOeE=CHT7fM(F;QC4y1b8EWHCoDn-vvP{D26wXwDoUA%duX(CTPt7E#&;auYMuec8`p$zn==e~8~uR&vYT zA0EtG5X4TU4CGFi)ktadII&~`NAeio@!GWI$6gJjSf@?*OX<7~IdfsiJ3(gyW{m4f_l*9Akuz(7ZTgP~jf2WL%r!=`Zp zK@r}wVzvs3oqA1q7bMoY0-{DjT@^7$;lWT7VdYhWhRq&I>Qz~@r%W+Ce%a^B9R6Qb zD^X-q8&DJq)~OXxdNizfvW0r&1VLhYL<2XVggpQ;w6l>6C0`AZf({nNnJ+}t<NWEz9)Si3O_j)QC7@Ff^$u!_ zv3o0N!L@`iUk$o(Nh|m3zCMBR6TrfuzuZgTp(n!Em!v{2L)g*FCpygR_h`w0YR$lUt?1kAwu)KhH&QW$ z^YHO9w8t7=TBOH|S+Ez!CGZzVDn6c7=L~!cxAE{g_x-*ldtd>%-YTIE7BGJF(T$&p zMMF6^i|ylwFCn^8K8cQzmWCpPX^H@m3z)w9EPjM3MA^q3$vJ6}z-NczfOUm(;SH3{>%f#v)G^n2YiAo9u|&|xY^!e|Djy(_#BlBC z4?qY83zR!@!Hgf}S$dKoOD*ihGTEvFU+gu;i0qABD82&W&3s*U!|vO>G`&oM#xyF;M24*cR@$KdGDlCxpP!nrJm~&c* zUGQaO$#@@k!)dwlHJ8tzd~BPCzmP4x@FIO-Ho-;9b>M^D3K8#na(Xf@7gZob)%7?6 zB6!c}7WlBe0>SHYQBlVEQOR;B+{y1&rJW=da&>|H+7$};jlrEsfEi+vhK*;3|0+{% zt+~U9(^*)3vHT_KHXKFQ&XoL7oLbBdNqZ<|+zJP1`u?_JvV3u%?O-UC+~+~tT@E8$ zWZUb;1$KwS#)Wyis-2ppyC$oi_+r?Pb%1D$7=)0a!O?Y6{_wszQrX8BU2g%77|DQm zX@%Vl)mtb8aVV#mK+dUYOo-EU=#7ff-iJ5NfV@?z?AQ4E9rRs9<}YydTuVgVzbOXT zKA7S{#-7jzu8yYry9BCcW)H+p%1JL~kgyE`5zZF50|D+c_p}QmQ{kgyF&@XLO5|^V zt`n9IV8OrZm4;#yW1JwV0QARr4~&Fc1h-!4$@65IxrZXqK3^--uD)v-hh16zOue$) z1lil@_Ijqaw1A!Fla|kc9~j%@3kc8QGt$8t6@Hi}+LJ3F8O@XRXHOHu-7p|+uN@xS z?uO?1jiTaCN@ksGfZQ!J+7+k(EX=@Sr%=k4uT!X&{IztjrvT->0wnzvB*{0h)nvR^ z6dKsX|UO$FJW1~8p!?JUkNfn{j$ei6q&ro65}srnQEiVSzmMH zRFhX)uTK0Bgkbo^pbhK^)>w75AToJ_Hgp@-!P~*mq|IeIwQ;Qldtl*gN@Udi1C@XE z%julR=s6ko02Us|+4-zHLLrx3n?F-j6;E+w@(WV&=h@q*bRlcMV4wu;z*wSPv08Dj zcaV`fQgZ>v;G8Ywm<>J>J!!0DTj$P(0jP-T>sy=F`{xHXt!!7?=Nu7Cj*?q#`9d zj-(&)h44TJ@MZWqJ6sZ@ZLl{mNg^U;TH!J13t@J@WXPGW)j26WK5@&n#;`}8a(a;< zzeiN7P~$#TkJ7$LPu)OSa9Nd7U~sdj+BE}X|7*+bYgq31;T!S9p--*PBt)^I!ur5k4vsVX9W{3NsM z&S0$ngN@NGkthN%A}ooR^-f?RTB+}Nt7<)a6T!=CJVUbf;goRyUUUGGlDD^?caZd5 z|E{9#=O^v5bD#6vQq4Pt6@`~{cQFt7H=kD?IMJ?eU1K5ITi(5A32M1^QzTPYxoL@1 zBNDqvS5Xg5yK6d{xRKCORpO08_Y)#OQjdHOB|nF;1UN29<0%0er+tg?IelK%s3AS( zMa<&!gy9$D(CfR09F{Dk6_GE)Skn}enveQ~PZG}6=P7M@+BO(~+uKB=ngv;bk;n*7 z_M{)`F$xMHC)Xd1kBp1$Jr|4YLfhK%+p^B?EGk($ad#J611g$2f7TphxZ=)$`xgZ* zQnRRTu)BoLENB%~Uc}?|sz!fw`A{*5aikp$sraFdWiUU&$G9^n47xKAON&jFFeF7+ z1cIK`(T%&M2knbw+ynv~EVytAU>PT{vHtnRP5M`B{eEyYyf_3)<1VSdZ_lvd1y%gS z$9b$VD7x73v)~5b=dy~Xp)le6(KEw7Q zMG;q_q4~&9E6f*BYcV~*qC@EZnt_edMZozK&@OQpw{Me{@Uje+Ho{eFqObpOYq|Ce zGPL$Maiz&Ic3GvQ$#F3~X*#Ix^ZG1LC0P?u8Xxk`aInC+5r&m7>znXO=is+(Ob(+m zCj@R=CL}Hpfz1^F1J#DdQS}wtBDhSUc{jsce8Zdl^X2b_IfIHa`_7d^s8nT`>uHo+ z9@2bgLe6^0!&pV{90p83WXRZZf(5QLs$ z*gqw67erQ|w?L6hL5F|#kt*2?MeH1M$I=~$m1)JKR`({RlX*MOn_-QP$dsn0?whfs z^aR$Z6&1l$ud3XWuWcMW(5Rn+DMT}{2 zna?$xc=ifz76E8*X*FWHF_<5Ocr87rF@2i8zrf_u^il8&mZ}U65P(3WL_MO%#!T^| zt;gASqi@4@g%s%ShVJGPHE`2NTPyX)hh!WKq(9c(=|8gj3W*>@(}0+G{F8tSZ}lwA z6o}GtJ)L*|#%Fty?uc1TS&g_OMKJR*+#PUHHB_C#vuL^r^jFesyxtIoZd3ny=PNKI zUgzeXftn;R-h_PlN#}#In(*&_muyybGUpb{k5PIC5$wy5t1RIo`g^Zmz_Zkm&&Tji z?e+BvCh>s4qwgzBZtV=7->84fhk%oA#wl_sQ0>*zLEvSGM z-HRGf@7qFt?}LP2jg1S5f%B39el*H^4)`&K$(?EB>=LfSZGBJJlULa=ZdWFHa>ZWxkI#R783`HO03T}| zDD6=%Z^vZZr#ICh2(aKX7xnp=y=kNhFABzBX!Wh&i_b|kF0HH1%W0O8?6lX_;T1I$ z)g8Yot_=#=>Da_PB0+#NB^JtePMY8PV!86tAYWt}GrT&X!`MXi)oJ;NgNx z&fyCh@HVtZj}Tk&Zm*pceA>Xz15!@zUoSRNA5Ui^xl-Yzsz>U`T3lV%!$@{lYo=s4 zJm&hr?820@?ox33k(n3RgQuy&_ zCU4rZ$H)80rWSVBP76g!s_=FWP|DVpzIxdQ??c)-nfOININl7j&%L3Ak zbf+{dwKOgZ2nL{tgn)E|l!U~Bw1jjDORdt~DJUTC;Qiju{rJ=yyE}i(HD}J5&z$*V z=lY)O_fxQp%?egk{1MJC$@^uV?zkE@R>6^j;LRs~bPVXQPqb#yY$fWdVI1rZ4x6`ZLeu7vX!&7$#^lhLo%08yPi9br@8p>4y|k z8NIW?%{Q9HShSja(|L1sFEKPykG?!H0oI6qTx>T`n2Hb#6S$D3z!t#f(AN=lf(bK7shl*%;ZmA5}r15y%7oK_|lje#qd7(h669iNDx4 zUgEDo-rmeZU&#`qpO!w3Kj%fb3e~d1iSDcg^M5F>+6_akH6o&-h>v}=pHBvFPT}WU zDA?XZnvE8&!tz^PufKbvLARue6@!zqDf!$$IE%c!L@N?ETKNQYzAv(2v2N2J@%4E_ z%Ug=)_hOyu8ZLSipk0lCP&Az8}{{jdYsfm4l9@<3oL=eil(m7FMXuKt$hFKutqStk_)*LvSOLcGQE6 zqsqgba^Yx`sIGuusEjpOlFvhT<*A_ooB1p0F*4@|a~{FZwVkxva+ZC)mD_j>h*Ava zR7j76%Ce9@T>8xFqqG$D?;O3OE85s_YB4IDmenW`zM`{N;TJr&t-W!&%ke~e@=I9P zgUJ)~z2)J?blo>Ak!%?aYhTLOIG{1lw;2M0gL*|>KTR6UE_oK`y%tE*QunCkD2c<$ z*Xx_X{-OUOSZL5`kmh5+3w+f#P7-{(C}X076uA1wfVjRR8NKr&FMTV_RD@#dhNN<_ zc^b*K-Io6|@HNEOgf09Uo?!#CgsrLmZl`&fwb9}83^B)3S2mwrj7~k&s@~i(j%E&J$|ePy+-O6y8MV45L-MXyhb1egFs1$=3KdE*s8=#Tq|IQS`vqo} zs;1wLrRhxc=b2hMu6ltw8fn9+Y?}P((A>#8W>^pSr3Lp1Xgm$(-qhT?LWqwvb_`AA zS;Mv7*b`@+Me3@5c76e?#L%1bmo2Fl)aYY7)>y~Q#0K@69id|0v55)N!}fJPy@VmQ zBz$0uC19ZsJn@M_b-h+u&vX$<3?IQn<`1%O31VkJzRVKy%;A}J;xHnV3>2bLuOMpg z=RD1vep1Jy`8-zaWCQQZEHWI%i`razdn@SGB4Rd&0-KL2t5&qCbB1WwZOFQnM@X?^rMGpJNwU(fN1>x}fxEG;Qnnp51%9d(V{+_Ex^YucN)=^T@6 z+*|M;CvmArMi96)oC*3gA03t1jLc&`WpY_T$ZY!GtVe{yyD9k{dvwO8)~{|BDq;0+ z(CGJpN~ZTd;y+*=HlC?YR}b`8X!ee^tEnxK!p+J#%phg_G#(zlII@VH`CfGF#mPsB z5IFuL((L^UFWeX2`>>7cor*cyFFgxx%xshtYjAYXw~P^*BT7b3U>Rj_IMLi(#E026 z5*sP}DEsC%zp6v2A;Ci=t7W=)2$C=;a^()U86hu}C%3hCP-l+zEsaLpLzR{>b`{r> z!#ahepz=Khx@>O4V zvC4MX*t`x5l2f+}nRF;1HKHOqWQU2AeVcpJx97|C$a8&+6~ z?vrG}Oa6LNL4sUQ!F&o`e&`!b85F+bl}kf7bH4U5`U-zdjuw7v(}Ub=J6BJwR?=)! z)uL6t+^OG_%8IeY3){u1h|28>6jWO7#yZ(y5|#hVDi_~n#k3DD=q_$oOWHeIi~Tyc zUEoLmiOyn?OcKxhB4TgQ*L{C+@=L(>Av|l%t2RZm^e0U*p4Q1f)4xkB^(VvlYneF! zNB&3oHif_FpW3C!)xSf4|1H4$|3H8O0sy7?OTrB*{4a2n5WsByz+8f$%aH(J_Dd#D z2v}wRAMn?|=;^XGR2UF#gZ_0M1boS|{@wRd1P%mXI{^1xqC8*)KNz^;OW-F62+oQA z+AfjbC0M+KfR~W)vM(_7*Sh~p01045q02D=(Di`eFHt?9$l+g2%YQ&<|8_S1o1+o@ zjiWIEvSz|UmmCdHH2Z_2K|ucpjz;j8t{Kz+O4kem68ep!UEYM>INIMogMV@~5fCt) ze_}L14ex&;Yqn&Jbf+6f2JP_jk>e^~!S$8yd`kHE8ucs|`79eg_D4BZ1?|zRtGMzy z&wY$u+bKQ#+*QtNnzz6j>zg{Ii-EHz4S3J5$-d-1>Ux#8mfIteX1`9qmAg<5?jDWp z7^%CBE_Eh5e^igFVC;!moZ+)SezeoL^XT}vu_oLL#%N{<+02a*X9v`A z;k2FQRWVHSU=?v&)ax*AIDz1mXn>NYWI+3B{S&u~UK_$s$eck**%XmbteiprVZ5j` zF~s!hxVHcD;<;Dv!M0nLly8x5V3O3S(&5s`CtX6kpFb3<9>BJPW>bePlukGXQy&<0 ztcV^4x%8Fzd46;@dYWW(hvMX@l6UjwD~XNWtj;}~KFXkr=4s!bQ(04UDQYp9*KDL- zqP`4a?noKBCdD_o22PFM2;g>IXcb!{NtlN9osIG8)()QujY-st!-SkC79kI9gbnA< z!jTadg%OhzUy{fx^K|ts8r`im^XL}E4g?5f-yO-QgjlQA6iG-9emL7NpM+lxr&K{4;3Zb#iH^SZt+`;stv~D_L>U}ni>iF zKY!V51xqBVwrfbsGng$BLd2B`g}k7N+W^cHv>_=?I#@OOE+h?6a#~O{C0MkXSYhb z@&)wACQ833o5z!p4{XII+jUN-j%|!j?T6gipD#^imsPkUy&Tu}Q(D>v8DST*z=F_hV?|Fab%G_>@e=m^kIjj(sHB@W-tGq) zZ*UYyWhAKLJ@hblZX5E{9IJC^3I~-9F4`(r8pWa3lgzO02=?n!#4&Md@6wQR1V$+B zBNc4GwIKnLMJh$&EY5jaWHCu#uxNjAE+jlAl;OpxtRA?KU@>Mzb-B$k$zIvInHft0 z;%sHB5i5qB*w+=l&q5nl*T>9RD`A+pM*}+$Wn=8>HE~iR_6pR2Ck5$&-z7sRYG3t@ z^4iH5s&K#m5X0v*ze^S|C_~Wyg$!L>q?SDe_8M2)1Zgq36h(8y$r{k0^USNKjO|&! zk{OjhdgGVRUqr+uj!h;wRL>N}!=XUrC~J@#jEJ)yv$VPhUNRvCY628c z=x`^_;J8COe-tk4^o?}W9a1#ClgbM+cvE78lLi$*SA{`r5>w+9&b5Z+%xNA!;=^nc z-mcL#_SaTVL|>GMg0CXWnVdCfd5h46v7FcQzPm^kh*HNLX!pO>a2-_N1_83>ulx@^ zYD}zANe^mu;Bdu-PgMqVSpYuESA`t9&t`criZh4UYh9gVpyh77enF0jeEigoigsA~ zpbEE8x)SLii1)n{hMHIZ>pEXEpaYx0f7o|KAOuBDPMW#q=*XF z%!KdpxicRPOe0={pZdP5s=UA0yxWtc^{f;Qa&&`JnC`~2v_iO+Dmf~`saqZ%Ya*zN zDURnE{eg~oGX-(#R@^c{=_$bL3Akw=j`LhKGJ0)uOG+A_94%&`{=%1%wuKt0ru zeehQ7hF+d1OLIuzM%Ij27n_`v6V6c76!of73HEsbk*t)H9Iy*I%&DgOp$#y#0)2g? zk!D5#L1i6*Ctee;77yjH6W1pvHFP!^?@OLddF)rrIy*_B_scD^UY-!_l7HRhV} z-?$RCQ=9j=nDd(wN)j>#qDPZo&~dT&60fS91b>(HRAa~iN&{+m_#*Gx6bOmBkQEej zUc(<~JOVjN-H+3Jhm(x256;bT)KBVawN`t*G^a2`_klto@@AC~1vQrL7=fOU4#vwc zn5X+EHwzDBWkgRIUeG;DIMBnXL+jcIzAO!BpMc8efyx|o@7LT=uG7Yw-i-{hW+kvdZ z4TDW4IczWAN#Y)mnoyPC+es~6TcqC2J9&$Zb3Li0eH9^-17>Or9r3E432jK_-ReJ* z%eoQf89YR^ArVSuGREI17bBeLxW0IA@YfefD?N^SXXde^Ncoc1*hBAK@1p(Lgy7O# zKr!%ItvsZT=o|O}+fG#fDqw0{pFG`Z=wg8S+2s`6lTFZ8RYW9DP3A{w5w5(Z8AC)I z;VAGTaaccZx8x+aRY%7BQ#35}mhtFq7iP*0ztoGFXTF=}%tx4ZUgO03qwhcOkQBd+ zmJT%TAR8U~sr-pJXO&1Edy%c8y@H+lew2)3+3Q&mSEd9BffAbU;y>{hOr;~o{i`Hr z)e20=`&lR9xOnkOf`pJp0 z?p=TWI4xN2Bi|9h`n0`tJ(kDqsT}i`aMFmSD>rSBtqVfc3A^47jB{&4fvqE1IPGAZ zs%P!7kL7?3dyh3!StREQF$FP}7tn|J9O?Va-ZyyO@(JOYIdx{Zw?~#(RzL93$Q-YE zl6lJl(O4jw_B7&}A-%83jw79bM>Ccywr}Vw4F?l~MolZatI8rUqG)%9ArFVA?gLhP zLj>q+N9j%T%s9DJ8N$-CQY2z>c-_y5qDdJ9q-9TTxIZ^sePpn+b{N=s1^?U&PkEK* zz2`*caRC;2>&j&-ob6C5zo-p~v}uaVgGA9o8SOnpc#Zitq5<(kCT8&x^FqO}9xKT0 zVHd(=%2ZK{$-ErjjMH0$`+g0Cg6!c5lhngq^d~)_t{KZVmi|y&m|TGF_iNU1cC|U4 z32yG!w(W)46pajSytn#!W%=QIjq;@aea3Qgj|liYf5p}r%@PSROudq^g1w=wF>)0$ zeSEX&q0vc3CVypy<>ofw$q#g~6y0ua8Akqa`{^z4)d2FA{@TJKDYGciL0trPwMd;~%P6 zyq*S4sx9P&=Sc~k_qjl4V1d&C{b#~s$wuyL8}o!GfLG|$R&kW54!WGUrr&zLZyllUz zNW&_k6W%ajkJw*tDhN3p`*7=aBp|{k_r#!P)*M#yu4!QOY>w^V`!vagegmCbO|AcF zNg5i0`euB0!qw;GR=;DmT3?#gca}QNOQc|Go1O6YZfMc*m@bpBE1&ub&>n(=8A#U^C!y1T^Sw~$zkhz#U|raDaIUPn((lUg<5IVXzGmK;M)W*NUiN>noVr(>B`szTe` z6}iXoi>lI2=<<>7+Qa~`#+ixroMuk0>8^{elhMbCC%2ec>0q+S1@kU_H=c;L zFQ4It^%Kj?F1Qq7p|fQi9gJ)6oErtgzpA#X*3D`$7ZR3+uTyH_&2vatg=A#7YQ8k7 zQN`c)xmTBWd??irw5VkZ8Wx=--&&{9LayDd@5I5XO z6ek|il3x(9y0T!#&;*g0=60snyK6;oRiX$h;1td`LZ8;b6Vz2%Vnm22k3t2ShKNyG{#l9iTY2Gcx@4jBX0kwHk^xpK!>picxF& ze0OG35!}NELzBEaNU>VLVQ$4#jP+)vKBXu)^CvqQkcWz~U3xlR)O$VK`>o$wgNi$= z0}&UarRgK}`(NQZ+xR5y6yPnanM|(fI<}ed1hEH+KN=|(8XOA)W(yA&tM|$+a4}>( ztT%(`svV`NTg3X&`mMnYNtv1Tye0}o9UY3b9*;O}<x<{t=;J5X*n>`g9ObXnH2T`|h&CD(++>7@ zG1K)(aUSo#o4;Kh&!*eh|HWnB%buD7of>8QVbVpcT`jLo*=g|$7OQB=NUSxlY0if; zz8Wh0?P`++0|ie4=MBZzhn(Fa`uPm^sh1KU5Y2lGs`@qXbwmxKyLwb|qv;lATP-sP zE?2B;28djlt@jRiLlh+D`p?f!)BJ@a>%YPSdvpVqmoA7ke;Bc%mu2Yp@SzDE!?(ix zvUQwhwd8B>Eka@_eJI{^aK_`ZvEA?HzFUZRZy4OFL|pK!Gqg_53#T=K;USt|qIaik zuMj?C^22#A-e)akZO=2wxAM5%zxZms&~4(gO}F87!E(BjTioS&aZ#@X^Pf}XSSpfv zt8@vG_)aI%rjmX$h3+xajz@U%pF-1;y^^L#!jdI_KGLcL8}>LViP?BZsv|`UjJo4J zDx8A+^IhoZ=*yf`k1m=xQnyzad4MWhz_30b_MCp&OF$GghR3*vpV0R5!z~WHUIjIL zf_nZKq1F#E#wwcoD&{Mt2clzT@Q4?U&qTf6VC;0$w%}ua9xV?sIPZDG^TfW?U5kcl zC3%f7_Y|P{b}Rf6?ybJ1x2{6ml+-dgtcU_V@Msyu76%P4xMXmUxVVq=Kf-6&-DbHq z!Px7X#givi5p3r1ao?$^QD;g+ZJN)wU_c{rWDOzgFCkrwubp&oQvs(|293-CRjWNX zGFD|JiCoto?D4;GSY4Knqk%aT89*24=ILFRbg1ehzac}2)G-rzFGZnWzE?r z0<%;)ip0++7mM~4pRb4J)t9;6rhRda6b?*MK49cm2!2!;(yRg%ak-ZAX#Q%KnERXS zZG055CI@PK`f@&*@6E2A`6cXiwh)OQ6gpkW#ns2#X|R zp9iL7pICwxQOtatIJ{#$H2 zwJ;u$35ujuBRWh5>CD9INze)@#oF|p$yEAye;9fs?e*)i?e-t>?jpDwY6qPsh<4Mi zct|08eokGFJ?i8Ar{k*%TcDJEUG0T2JZEm6p=1~3juMrhX$i1;u+klpz)#1;HV)@I zFNdp@Oc;X1ca{A$_um-e$<*K3&>^EWSF??G zZe}Z$P-MWyYN(wB4SzYcp2a=F1fGM*I7V9$jBZxPiST18Yqqmy&Vo=L3bUPq@p_N& zgoe@|_H|EqcG-`yw#SV~{16t-Al5mH4%f4l6uTTyi-<;L?Ddw6iW0N;@E3W;4yfl# zM(JCh?osKB(Iga;q)SetDKyvN4cvvX%f1J)xC<4Tw<`L*BjgpMGI+N+(*v2re9l(O zy-WwFG#N5*dV+9*3MTgdIUoB=sN`=6Sx0ZcV}Mf-3=#$6@_-Qsle(Rk1Ctr25Fdz7 z$m}j3%+t!=-o@@N;LhRcX6s{P=gGtgx3baHWiqhy^m24_1yX!`5a0w^A4folMG&kA z6*ardr0rwn>Fvh^814PC@ALJ(OTaJV=a92mAKSpJO@(F_fJO+#fTp)0@@?wG@K_L*}u^}J`r2Yg=Kp+m_2aKTZ zX8WI;{GHi>ucw_okfaq9AOQXC!z2v3^xLp!`XeSF1O`&Czm77w{uzT_dSCn=1NHzf zkl$khLPD2m*~`!0pDPFmlKewV2yo;0JthcbdV#d?Z|%S!!Al2_-(%2URVly40F#GH zPm|wcP$9te;~!!o|2&3(2pC8e|K3gz^2<%+xBdhnP@#XmJ`urx90M!>0_-h*?+*+W z0Raj1-}(cKfP{dw^=~mDV0QoR-g|pm0iG3}1eZE4x{iK!z`Oxgk#25)+013CTL&=B zaJ6@1`t@*M?#Kg{EaD)j71UNl$POxCB>)l@wzIVpvauJkhuVljpn2hUWkP literal 0 HcmV?d00001 diff --git a/docs/img/data-contract-diagram-v3.png b/docs/img/data-contract-diagram-v3.png new file mode 100644 index 0000000000000000000000000000000000000000..c219a97536ead8b663ff4ca69f9411b126a0143f GIT binary patch literal 921567 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%0A<%3goHZERJXzT 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 literal 0 HcmV?d00001 diff --git a/docs/img/data-contract-diagram-v3.svg b/docs/img/data-contract-diagram-v3.svg new file mode 100644 index 0000000..152b428 --- /dev/null +++ b/docs/img/data-contract-diagram-v3.svg @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + Data Contract Vert - v3 + + bg + + + + + + Layer 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Applications + + + + + + Monitoring + + + + + + Observability + + + + + + Notification + + + + + + Tools + + + + + + Enterprise Data + Governance + + + + + + Enterprise Data + Catalog + + + + + + Enterprise Security + & Audit + + + + + + Enterprise Ops + + + + + + Open Data Contract Standard v3 + + + + + + Data Engineers + + + + + + Data Scientists + + + + + + Data Product + Owners + + + + + + Automation Tools + + + + + + + + Name, + Version, + Descriptions… + + + + + + + + History of team + members + + + + + + + + Latency, retention, + frequency… + + + + + + + + Data quality rules, + Data governance + policies + + + + + + + + Logical + representation & + physical + implementation + + + + + + + + Servers, environment, + and storage + + + + + + + + Internal or external + costs associated to + usage + + + + + + + + Roles + + + + + + Fundamentals + + + + + + Schema* + + + + + + SLA + + + + + + Data Quality* + + + + + + Team + + + + + + Infrastructure** + + + + + + Pricing + + + + + + Security + + + + + + + + Enterprise-level consumers & + contributors + + + + + + + + Contributors to the data + contract + + + + + + + + Consumers of the data + contract + + + + + + + + + + + + + + + + + + + + + + + Data QoS applied to + your business needs + + + + + + Business rules*** + + + + + + + + Room for + custom needs + + + + + + Custom + + + + + + + + * Major evolution in v3 + ** New in v3 + *** Scheduled for v3.1 + + + + + + From ea56e775b7a821e0bf29e0fc08121f19a9f15cab Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Mon, 29 Jul 2024 09:03:00 -0400 Subject: [PATCH 10/93] Move articles --- README.md | 28 +++++----------------------- resources.md | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 resources.md diff --git a/README.md b/README.md index 7b87ea0..6e6b89c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Welcome! Thanks for your interest and for taking the time to come here! ❤️ ## Executive summary -This standard describes a structure for a **data contract**. Its current version is v2.2.2. It is available for you as an Apache 2.0 license. Contributions are welcome! +This standard describes a structure for a **data contract**. Its current version is v3.0.0. It is available for you as an Apache 2.0 license. Contributions are welcome! ## Discover the open standard A reader-friendly version of the standard can be found on its [dedicated site](https://bitol-io.github.io/open-data-contract-standard/). @@ -32,7 +32,7 @@ A data contract defines the agreement between a data producer and consumers. A d * [Security & stakeholders](docs/standard.md#stakeholders). * [Custom properties](docs/standard.md#other-properties). -![Data contract schema](docs/img/data-contract-v2.2.1-schema.svg "Data contract schema") +![Data contract schema](docs/img/data-contract-diagram-latest.svg "Data contract schema") *Figure 1: illustration of a data contract, its principal contributors, sections, and usage.* @@ -44,29 +44,11 @@ validation of your YAML files. Links below show how you can import the schema: - [IntelliJ](https://www.jetbrains.com/help/idea/json.html#ws_json_schema_add_custom) - [VS Code](https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings) -## Contributing to the project -Check out the [CONTRIBUTING](./CONTRIBUTING.md) file. - ## Articles and Other Resources +Check out the [resources](./resources.md) page. -* 2024-06-12 - [The Future of Data Management: An Enabler of AI Development? A Basic Illustration with RAG, Open Standards, and Data Contracts](https://blog.owulveryck.info/2024/06/12/the-future-of-data-management-an-enabler-of-ai-development-a-basic-illustration-with-rag-open-standards-and-data-contracts.html) -* 2024-05-30 - [ODCS Roadmap](https://medium.com/abeadata/odcs-roadmap-9b9a17367af4) -* 2024-05-25 - [Conceptual model of Data Quality of Service as Code by Jarkko Moilanen](https://aidausergroup.org/2024/05/25/aida-user-group-forecaster-pi-day-highlights-data-quality-whats-new/) -* 2024-02-06 - [Getting started with ODCS](https://medium.com/abeadata/getting-started-with-odcs-3ba790707879) -* 2023-12-08 - [Why the Need for Standardizing Data Contracts?](https://medium.com/abeadata/why-the-need-for-standardizing-data-contracts-133bc3491148) -* 2023-11-30 - [Linux Foundation AI & Data - Bitol Joins LF AI & Data as New Sandbox Project](https://lfaidata.foundation/blog/2023/11/30/bitol-joins-lf-ai-data-as-new-sandbox-project/) -* 2023-11-30 - [AIDAUG - Bitol Joins LF AI & Data as New Sandbox Project](https://aidausergroup.org/2023/11/30/bitol-joins-lf-ai-data-as-new-sandbox-project/) -* 2023-11-22 - [What is, and what isn’t, a data contract](https://datacreation.substack.com/p/what-is-and-what-isnt-a-data-contract) -* 2023-10-01 - [Data Contracts: A Bridge Connecting Two Worlds](https://medium.com/@atanas.iliev.ai/data-contracts-a-bridge-connecting-two-worlds-404eff1d970d) -* 2023-09-10 - [Data Contracts 101](https://medium.com/p/568a9adbf9a9) -* 2023-08-10 - [Welcome to the Open Data Contract Standard](https://jgp.ai/2023/08/09/welcome-to-the-open-data-contract-standard/) -* 2023-05-11 - [Data Contracts – Everything You Need to Know](https://www.montecarlodata.com/blog-data-contracts-explained/) -* 2023-05-07 - [Data Engineering Weekly #130 - Data Contract in the Wild with PayPal’s Data Contract Template](https://www.dataengineeringweekly.com/p/data-engineering-weekly-130) -* 2023-05-06 - [PayPal เปิด Data Contract เป็น Open Source Template ให้ไปใช้งานกัน](https://discuss.dataengineercafe.io/t/paypal-data-contract-open-source-template/581/1) -* 2023-05-05 - [Jonathan Neo (j__neo ) on Reddit](https://www.reddit.com/r/dataengineering/comments/137glbo/comment/jixw5hj/?utm_source=reddit&utm_medium=web2x&context=3) -* 2023-05-01 - [PayPal open sources its data contract template](https://jgp.ai/2023/05/01/paypal-open-sources-its-data-contract-template/) - -If you spot an article about the Open Data Contract Standard, make a pull request! +## Contributing to the project +Check out the [CONTRIBUTING](./CONTRIBUTING.md) page. ## More diff --git a/resources.md b/resources.md new file mode 100644 index 0000000..2ef37a7 --- /dev/null +++ b/resources.md @@ -0,0 +1,34 @@ +# Articles & Other Resources + +## Articles + +* 2024-07-17 - [Data Contracts in Action: Testing](https://medium.com/@pflooky/data-contracts-in-action-testing-111631338657) +* 2024-06-12 - [The Future of Data Management: An Enabler of AI Development? A Basic Illustration with RAG, Open Standards, and Data Contracts](https://blog.owulveryck.info/2024/06/12/the-future-of-data-management-an-enabler-of-ai-development-a-basic-illustration-with-rag-open-standards-and-data-contracts.html) +* 2024-05-30 - [ODCS Roadmap](https://medium.com/abeadata/odcs-roadmap-9b9a17367af4) +* 2024-05-25 - [Conceptual model of Data Quality of Service as Code by Jarkko Moilanen](https://aidausergroup.org/2024/05/25/aida-user-group-forecaster-pi-day-highlights-data-quality-whats-new/) +* 2024-02-06 - [Getting started with ODCS](https://medium.com/abeadata/getting-started-with-odcs-3ba790707879) +* 2023-12-08 - [Why the Need for Standardizing Data Contracts?](https://medium.com/abeadata/why-the-need-for-standardizing-data-contracts-133bc3491148) +* 2023-11-30 - [Linux Foundation AI & Data - Bitol Joins LF AI & Data as New Sandbox Project](https://lfaidata.foundation/blog/2023/11/30/bitol-joins-lf-ai-data-as-new-sandbox-project/) +* 2023-11-30 - [AIDAUG - Bitol Joins LF AI & Data as New Sandbox Project](https://aidausergroup.org/2023/11/30/bitol-joins-lf-ai-data-as-new-sandbox-project/) +* 2023-11-22 - [What is, and what isn’t, a data contract](https://datacreation.substack.com/p/what-is-and-what-isnt-a-data-contract) +* 2023-10-01 - [Data Contracts: A Bridge Connecting Two Worlds](https://medium.com/@atanas.iliev.ai/data-contracts-a-bridge-connecting-two-worlds-404eff1d970d) +* 2023-09-10 - [Data Contracts 101](https://medium.com/p/568a9adbf9a9) +* 2023-08-10 - [Welcome to the Open Data Contract Standard](https://jgp.ai/2023/08/09/welcome-to-the-open-data-contract-standard/) +* 2023-05-11 - [Data Contracts – Everything You Need to Know](https://www.montecarlodata.com/blog-data-contracts-explained/) +* 2023-05-07 - [Data Engineering Weekly #130 - Data Contract in the Wild with PayPal’s Data Contract Template](https://www.dataengineeringweekly.com/p/data-engineering-weekly-130) +* 2023-05-06 - [PayPal เปิด Data Contract เป็น Open Source Template ให้ไปใช้งานกัน](https://discuss.dataengineercafe.io/t/paypal-data-contract-open-source-template/581/1) +* 2023-05-05 - [Jonathan Neo (j__neo ) on Reddit](https://www.reddit.com/r/dataengineering/comments/137glbo/comment/jixw5hj/?utm_source=reddit&utm_medium=web2x&context=3) +* 2023-05-01 - [PayPal open sources its data contract template](https://jgp.ai/2023/05/01/paypal-open-sources-its-data-contract-template/) + +If you spot an article about the Open Data Contract Standard, make a pull request! + +## Books + +* 2024-09-01 - **Implementing Data Mesh** [O'Reilly](https://www.oreilly.com/library/view/implementing-data-mesh/9781098156213/), [Amazon](https://amzn.to/3ysN3Jf): in Chapter 5, ODCS is extensively used & described. +* 2024-01-20 - **Data Contracts for all ages** [Amazon](https://amzn.to/3Wl1My1). + +If you spot a book about the Open Data Contract Standard, make a pull request! + +## Videos + +If you spot a video about the Open Data Contract Standard, make a pull request! From bbdf71afd6644470be5786d2f70ceac05079216e Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Mon, 29 Jul 2024 09:05:51 -0400 Subject: [PATCH 11/93] Update resources.md --- resources.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources.md b/resources.md index 2ef37a7..0e16bec 100644 --- a/resources.md +++ b/resources.md @@ -24,8 +24,8 @@ If you spot an article about the Open Data Contract Standard, make a pull reques ## Books -* 2024-09-01 - **Implementing Data Mesh** [O'Reilly](https://www.oreilly.com/library/view/implementing-data-mesh/9781098156213/), [Amazon](https://amzn.to/3ysN3Jf): in Chapter 5, ODCS is extensively used & described. -* 2024-01-20 - **Data Contracts for all ages** [Amazon](https://amzn.to/3Wl1My1). +* 2024-09-01 - **Implementing Data Mesh**, [O'Reilly](https://www.oreilly.com/library/view/implementing-data-mesh/9781098156213/), [Amazon](https://amzn.to/3ysN3Jf): in Chapter 5, ODCS is extensively used & described. +* 2024-01-20 - **Data Contracts for all ages**, [Amazon](https://amzn.to/3Wl1My1). If you spot a book about the Open Data Contract Standard, make a pull request! From 8e3e4fad619e63fcfd3977db6364d4381f33d73b Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Mon, 29 Jul 2024 14:55:03 -0400 Subject: [PATCH 12/93] Cleanup --- docs/standard.md | 172 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 121 insertions(+), 51 deletions(-) diff --git a/docs/standard.md b/docs/standard.md index 8c85d67..7d23b4d 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -6,9 +6,10 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color # Open Data Contract Standard -## Executive summary +## Executive Summary This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. It is divided in multiple sections: [demographics](#demographics), [dataset & schema](#dataset-and-schema), [data quality](#data-quality), [pricing](#pricing), [stakeholders](#stakeholders), [roles](#roles), [service-level agreement](#service-level-agreement), and [other properties](#other-properties). Each section starts with at least an example followed by definition of each field/key. + ## Table of content * [Fundamentals (fka demographics)](#demographics) @@ -21,11 +22,13 @@ This document describes the keys and values expected in a YAML data contract, pe * [Custom & other properties](#other-properties) * [Examples](#full-example) + ## Notes * This contract is containing example values, we reviewed very carefully the consistency of those values, but we cannot guarantee that there are no errors. If you spot one, please raise an [issue](https://github.com/AIDAUserGroup/open-data-contract-standard/issues). * Some fields have `null` value: even if it is equivalent to not having the field in the contract, we wanted to have the field for illustration purpose. -* This contract leverages BigQuery but should be **platform agnostic**. If you think it is not the case, please raise an [issue](https://github.com/AIDAUserGroup/open-data-contract-standard/issues). +* This contract should be **platform agnostic**. If you think it is not the case, please raise an [issue](https://github.com/AIDAUserGroup/open-data-contract-standard/issues). + ## Fundamentals This section contains general information about the contract. @@ -65,7 +68,7 @@ tags: null | id | ID | Yes | A unique identifier used to reduce the risk of dataset name collisions, such as a UUID. | | name | Name | No | Name of the data contract. | | version | Version | Yes | Current version of the data contract. | -| status | Status | Yes | Current status of the data contract. | +| status | Status | Yes | Current status of the data contract. | | tenant | Tenant | No | Indicates the property the data is primarily associated with. Value is case insensitive. | | domain | Domain | No | Name of the logical data domain. | | dataProduct | Data Product | No | The name of the data product. | @@ -74,10 +77,13 @@ tags: null | description.limitations | Limitations | No | Technical, compliance, and legal limitations for using the data. | | description.usage | Usage | No | How to use the data. | + ## Schema -This section describes the dataset and the schema of the data contract. It is the support for data quality, which is detailed in the next section. +This section describes the schema of the data contract. It is the support for data quality, which is detailed in the next section. Schema supports both a business representation of -### Example +### Examples + +#### Complete schema ```YAML schema: @@ -107,7 +113,7 @@ schema: criticalDataElement: false tags: [] classification: public - transformSourceTables: + transformSourceObjects: - table_name_1 - table_name_2 - table_name_3 @@ -153,48 +159,97 @@ schema: encryptedName: rcvr_cntry_code_encrypted ``` +#### Simple Array + +```yaml +schema: + - name: AnObject + logicalType: object + properties: + - name: street_lines + logicalType: array + items: + logicalType: string +``` + +#### Array of Objects + +```yaml +schema: + - name: AnotherObject + logicalType: object + properties: + - name: x + logicalType: array + items: + logicalType: object + properties: + - name: id + logicalType: uuid + physicalType: VARCHAR(40) + - name: zip + logicalType: string + physicalType: VARCHAR(15) +``` + ### Definitions Note: the description needs to be updated. +#### Schema + | Key | UX label | Required | Description | |--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| schema | schema | Yes | Array. A list of tables within the schema to be cataloged. | -| schema.table | Table | Yes | Name of the table being cataloged; the value should only contain the table name. Do not include the project or schema name in the value. | -| schema.table.physicalName | Physical Name | No | Physical name of the table, default value is table name + version separated by underscores, as `table_1_2_0`. | -| schema.table.description | Description | No | Description of the schema. | -| schema.table.authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard. | -| schema.table.dataGranularity | Data Granularity | No | Granular level of the data in the table. Example would be `pmt_txn_id`. | -| schema.table.columns | Columns | Yes | Array. A list of columns in the table. | -| schema.table.columns.column | Column | Yes | The name of the column. | -| schema.table.columns.column.isPrimaryKey | Primary Key | No | Boolean value specifying whether the column is primary or not. Default is false. | -| schema.table.columns.column.primaryKeyPosition | Primary Key Position | No | If column is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1. | -| schema.table.columns.column.businessName | Business Name | No | The business name of the column. | -| dataset.table.columns.column.logicalType | Logical Type | Yes | The logical column datatype. One of `string`, `date`, `number`, `integer`, `object`, `array` or `boolean`. | -| dataset.table.columns.column.logicalTypeOptions | Logical Type Options | No | Additional optional metadata to describe the logical type. See [here](#logical-type-options) for more details about supported options for each `logicalType`. | -| dataset.table.columns.column.physicalType | Physical Type | Yes | The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT. | -| schema.table.columns.column.description | Description | No | Description of the column. | -| schema.table.columns.column.isNullable | Nullable | No | Indicates if the column may contain Null values; possible values are true and false. Default is false. | -| schema.table.columns.column.isUnique | Unique | No | Indicates if the column contains unique values; possible values are true and false. Default is false. | -| schema.table.columns.column.partitionStatus | Partition Status | No | Indicates if the column is partitioned; possible values are true and false. | -| schema.table.columns.column.partitionKeyPosition | Partition Key Position | No | If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1. | -| schema.table.columns.column.clusterStatus | Cluster Status | No | Indicates of the column is clustered; possible values are true and false. | -| schema.table.columns.column.clusterKeyPosition | Cluster Key Position | No | If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1. | -| schema.table.columns.column.classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5. | -| schema.table.columns.column.authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on column logic or values; examples would be URL to a GitHub repo, Collibra, on another tool. | -| schema.table.columns.column.encryptedColumnName | Encrypted Column Name | No | The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`. | -| schema.table.columns.column.transformSourceTables | Transform Source Tables | No | List of sources used in column transformation. | -| schema.table.columns.column.transformLogic | Transform Logic | No | Logic used in the column transformation. | -| schema.table.columns.column.transformDescription | Transform Description | No | Describes the transform logic in very simple terms. | -| schema.table.columns.column.sampleValues | Sample Values | No | List of sample column values. | -| schema.table.columns.column.criticalDataElementStatus | Critical Data Element Status | No | True or false indicator; If element is considered a critical data element (CDE) then true else false. | -| schema.table.columns.column.tags | Tags | No | A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level. | +| schema | schema | Yes | Array. A list of elements within the schema to be cataloged. | + +#### Applicable to Elements (either Objects or Properties) + +| Key | UX label | Required | Description | +|--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| physicalName | Physical Name | No | Physical name. | +| description | Description | No | Description of the element. | +| businessName | Business Name | No | The business name of the element. | +| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. See `authoritativeDefinitions` below. | +| tags | Tags | No | A list of tags that may be assigned to the elements (object or property); the tags keyword may appear at any level. | + +#### Applicable to Objects + +| Key | UX label | Required | Description | +|--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| dataGranularityDescription | Data Granularity | No | Granular level of the data in the table. Example would be "Aggregation by country." | + +#### Applicable to Properties + +Some keys are more applicable when the described property is a column. + +| Key | UX label | Required | Description | +|--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| primaryKey | Primary Key | No | Boolean value specifying whether the field is primary or not. Default is false. | +| primaryKeyPosition | Primary Key Position | No | If field is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1. | +| logicalType | Logical Type | Yes | The logical field datatype. One of `string`, `date`, `number`, `integer`, `object`, `array` or `boolean`. | +| logicalTypeOptions | Logical Type Options | No | Additional optional metadata to describe the logical type. See [here](#logical-type-options) for more details about supported options for each `logicalType`. | +| physicalType | Physical Type | Yes | The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT. | +| description | Description | No | Description of the column. | +| required | Required | No | Indicates if the column may contain Null values; possible values are true and false. Default is false. | +| unique | Unique | No | Indicates if the column contains unique values; possible values are true and false. Default is false. | +| partitionStatus | Partition Status | No | Indicates if the column is partitioned; possible values are true and false. | +| partitionKeyPosition | Partition Key Position | No | If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1. | +| clusterStatus | Cluster Status | No | Indicates of the column is clustered; possible values are true and false. | +| clusterKeyPosition | Cluster Key Position | No | If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1. | +| classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5. | +| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on column logic or values; examples would be URL to a GitHub repo, Collibra, on another tool. | +| encryptedColumnName | Encrypted Column Name | No | The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`. | +| transformSourceObjects | Transform Sources | No | List of objects in the data source used in the transformation. | +| transformLogic | Transform Logic | No | Logic used in the column transformation. | +| transformDescription | Transform Description | No | Describes the transform logic in very simple terms. | +| examples | Example Values | No | List of sample column values. | +| criticalDataElement | Critical Data Element Status | No | True or false indicator; If element is considered a critical data element (CDE) then true else false. | +| items | Items | No | List of items in an array (only applicable when `logicalType: array`) | ### Logical Type Options Additional metadata options to more accurately define the data type. - | Data Type | Key | UX Label | Required | Description | |----------------|------------------|--------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | array | maxItems | Maximum Items | No | Maximum number of items. | @@ -228,6 +283,7 @@ Updated in ODCS (Open Data Contract Standard) v2.2.1. | type | Definition type | Yes | Type of definition for authority: v2.2.1 adds standard values: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`. | | url | URL to definition | Yes | URL to the authority. | + ## Data quality This section describes data quality rules & parameters. They are tightly linked to the schema described in the previous section. @@ -384,7 +440,7 @@ The UX label is the label used in the UI and other user experiences. It is not l | Key | UX label | Required | Description | |-------------------------|--------------------|----------|---------------------------------------------------------------------------------------------------| -| team | Stakeholders | No | Array | +| team | Stakeholders | No | Array. | | team.username | Username | No | The stakeholder's username or email. | | team.role | Role | No | The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role. | | team.dateIn | Date In | No | The date when the user became a stakeholder. | @@ -421,15 +477,16 @@ roles: | Key | UX label | Required | Description | |----------------------------|---------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------| -| roles | Roles | Yes | Array. A list of roles that will provide user access to the dataset. | -| roles.role | Role | Yes | Name of the IAM role that provides access to the datase. | -| roles.description | Description | No | Description of the IAM role and its permissions. | -| roles.access | Access | No | The type of access provided by the IAM role. | -| roles.firstLevelApprovers | 1st Level Approvers | No | The name(s) of the first-level approver(s) of the role. | -| roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role. | +| roles | Roles | No | Array. A list of roles that will provide user access to the dataset. | +| roles.role | Role | Yes | Name of the IAM role that provides access to the datase. | +| roles.description | Description | No | Description of the IAM role and its permissions. | +| roles.access | Access | No | The type of access provided by the IAM role. | +| roles.firstLevelApprovers | 1st Level Approvers | No | The name(s) of the first-level approver(s) of the role. | +| roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role. | + -## Service-level agreement (SLA) -This section describes the service-level agreements (SLA). SLA have been extended in version v2.1.0. +## Service-Level Agreement (SLA) +This section describes the service-level agreements (SLA). * Use the `Table.Column` to indicate the number to do the checks on, as in `SELECT txn_ref_dt FROM tab1`. * Separate multiple table.columns by a comma, as in `table1.col1`, `table2.col1`, `table1.col2`. @@ -483,8 +540,8 @@ slaProperties: | slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | -## Other properties -This section covers other properties you may find in a data contract. +## Custom Properties +This section covers custom properties you may find in a data contract. ### Example @@ -496,8 +553,6 @@ customProperties: value: property.value - property: dataprocClusterName # Used for specific applications like Elevate value: [cluster name] - -contractCreatedTs: 2022-11-15 02:59:43 ``` ### Definitions @@ -507,9 +562,24 @@ contractCreatedTs: 2022-11-15 02:59:43 | customProperties | Custom Properties | No | A list of key/value pairs for custom properties. Initially created to support the REF ruleset property. | | customProperties.property | Property | No | The name of the key. Names should be in camel case–the same as if they were permanent properties in the contract. | | customProperties.value | Value | No | The value of the key. | -| contractCreatedTs | Contract Created UTC | No | Timestamp in UTC of when the data contract was created. | +## Other Properties +This section covers other properties you may find in a data contract. + +### Example + +```YAML +contractCreatedTs: 2022-11-15 02:59:43 +``` + + +### Other properties definition + +| Key | UX label | Required | Description | +|---------------------------|----------------------|----------|-------------------------------------------------------------------------------------------------------------------| +| contractCreatedTs | Contract Created UTC | No | Timestamp in UTC of when the data contract was created. | + ## Full example [Check full example here.](examples/all/full-example.yaml) From 009430e455653be05749d822fc2da6e57321c9b4 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Mon, 29 Jul 2024 15:50:19 -0400 Subject: [PATCH 13/93] Lots of cleanup. --- docs/standard.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/standard.md b/docs/standard.md index 7d23b4d..b6a1dd5 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -7,20 +7,21 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color # Open Data Contract Standard ## Executive Summary -This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. It is divided in multiple sections: [demographics](#demographics), [dataset & schema](#dataset-and-schema), [data quality](#data-quality), [pricing](#pricing), [stakeholders](#stakeholders), [roles](#roles), [service-level agreement](#service-level-agreement), and [other properties](#other-properties). Each section starts with at least an example followed by definition of each field/key. +This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. It is divided in multiple sections: [fundamentals (fka demographics)](#fundamentals), [schema](#schema), [data quality](#data-quality), [pricing](#pricing), [team](#team), [roles](#roles), [service-level agreement](#service-level-agreement), and [other/custom properties](#custom-properties). Each section starts with at least an example followed by definition of each field/key. ## Table of content -* [Fundamentals (fka demographics)](#demographics) -* [Schema](#dataset-and-schema) -* [Data quality](#data-quality) -* [Pricing](#pricing) -* [Team](#stakeholders) -* [Roles](#roles) -* [Service-level agreement](#service-level-agreement) -* [Custom & other properties](#other-properties) -* [Examples](#full-example) +1. [Fundamentals (fka demographics)](#fundamentals) +1. [Schema](#schema) +1. [Data quality](#data-quality) +1. [Pricing](#pricing) +1. [Team](#team) +1. [Roles](#roles) +1. [Service-level agreement](#service-level-agreement) +1. [Infrastructures & servers]() +1. [Custom & other properties](#custom-properties) +1. [Examples](#full-example) ## Notes @@ -539,6 +540,8 @@ slaProperties: | slaProperties.element | Element(s) | No | Element(s) to check on. Multiple elements should be extremely rare and, if so, separated by commas. | | slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | +## Infrastructure & servers +TBD ## Custom Properties This section covers custom properties you may find in a data contract. From e227bc78e03e73e8350f9b5f1182ed8228d15874 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Mon, 29 Jul 2024 16:00:06 -0400 Subject: [PATCH 14/93] Update odcs-json-schema-latest.json --- schema/odcs-json-schema-latest.json | 794 +--------------------------- 1 file changed, 1 insertion(+), 793 deletions(-) diff --git a/schema/odcs-json-schema-latest.json b/schema/odcs-json-schema-latest.json index 81cce37..7097ad7 100644 --- a/schema/odcs-json-schema-latest.json +++ b/schema/odcs-json-schema-latest.json @@ -1,793 +1 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "title": "Open Data Contract Standard (OCDS)", - "description": "An open data contract specification to establish agreement between data producers and consumers.", - "type": "object", - "properties": { - "version": { - "type": "string", - "description": "Current version of the data contract." - }, - "kind": { - "type": "string", - "default": "DataContract", - "description": "The kind of file this is. Valid value is `DataContract`.", - "enum": ["DataContract"] - }, - "apiVersion": { - "type": "string", - "default": "v3.0.0", - "description": "Version of the standard used to build data contract. Default value is v3.0.0.", - "pattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+" - }, - "uuid": { - "type": "string", - "description": "A unique identifier used to reduce the risk of dataset name collisions; initially the UUID will be created using a UUID generator tool ([example](https://www.uuidgenerator.net/)). However, we may want to develop a method that accepts a seed value using a combination of fields–such as name, kind and source–to create a repeatable value." - }, - "datasetKind": { - "type": "string", - "description": "The kind of dataset being cataloged; Expected values are `virtualDataset` or `managedDataset`.", - "examples": ["virtualDataset", "managedDataset"] - }, - "userConsumptionMode": { - "type": "string", - "description": "List of data modes for which the dataset may be used. Expected sample values might be `analytical` or `operational`.
Note: in the future, this will probably be replaced by ports.", - "examples": ["analytical", "operational"] - }, - "type": { - "type": "string", - "description": "Identifies the types of objects in the dataset. For BigQuery or any other database, the expected value would be Tables.", - "examples": ["Tables"] - }, - "tenant": { - "type": "string", - "description": "Indicates the property the data is primarily associated with. Value is case insensitive." - }, - "tags": { - "type": "array", - "description": "A list of tags that may be assigned to the dataset, table or column; the `tags` keyword may appear at any level.", - "items": { - "type": "string" - } - }, - "status": { - "type": "string", - "description": "Current status of the dataset. Valid values are `production`, `test`, or `development`.", - "examples": ["production", "test", "development"] - }, - "sourceSystem": { - "type": "string", - "description": "The system where the dataset resides. Expected value can be BigQuery.", - "examples": ["BigQuery"] - }, - "sourcePlatform": { - "type": "string", - "description": "The platform where the dataset resides. Expected value is GoogleCloudPlatform, IBMCloud, Azure...", - "examples": ["GoogleCloudPlatform", "IBMCloud", "Azure", "AWS"] - }, - "server": { - "type": "string", - "description": "The server where the dataset resides." - }, - "quantumName": { - "type": "string", - "description": "The name of the data quantum or data product." - }, - "productSlackChannel": { - "type": "string", - "description": "Slack channel of the team responsible for maintaining the dataset." - }, - "productFeedbackUrl": { - "type": "string", - "description": "The URL for submitting feedback to the team responsible for maintaining the dataset." - }, - "productDl": { - "type": "string", - "description": "The email distribution list (DL) of the persons or team responsible for maintaining the dataset." - }, - "username": { - "type": "string", - "description": "User credentials for connecting to the dataset; how the credentials will be stored/passed is outside of the scope of the contract." - }, - "password": { - "type": "string", - "description": "User credentials for connecting to the dataset; how the credentials will be stored/passed is out of the scope of this contract." - }, - "driverVersion": { - "type": "string", - "description": "The version of the connection driver to be used to connect to the dataset." - }, - "driver": { - "type": "string", - "description": "The connection driver required to connect to the dataset." - }, - "description": { - "type": "object", - "description": "High level description of the dataset.", - "properties": { - "usage": { - "type": "string", - "description": "Intended usage of the dataset." - }, - "purpose": { - "type": "string", - "description": "Purpose of the dataset." - }, - "limitations": { - "type": "string", - "description": "Limitations of the dataset." - } - } - }, - "project": { - "type": "string", - "description": "Associated project name, can be used for billing or administrative purpose. Used to be datasetProject." - }, - "datasetName": { - "type": "string", - "description": "May be required in cloud instance like GCP BigQuery dataset name." - }, - "datasetDomain": { - "type": "string", - "description": "Name of the logical domain dataset the contract describes. This field is only required for output data contracts.", - "examples": ["imdb_ds_aggregate", "receiver_profile_out", "transaction_profile_out"] - }, - "database": { - "type": "string", - "description": "The database where the dataset resides." - }, - "dataset": { - "type": "array", - "items": { - "$ref": "#/$defs/Dataset" - } - }, - "price": { - "$ref": "#/$defs/Pricing" - }, - "stakeholders": { - "type": "array", - "items": { - "$ref": "#/$defs/Stakeholder" - } - }, - "roles": { - "type": "array", - "description": "A list of roles that will provide user access to the dataset.", - "items": { - "$ref": "#/$defs/Role" - } - }, - "slaDefaultColumn": { - "type": "string", - "description": "Columns (using the Table.Column notation) to do the checks on. By default, it is the partition column." - }, - "slaProperties": { - "type": "array", - "description": "A list of key/value pairs for SLA specific properties. There is no limit on the type of properties (more details to come).", - "items": { - "$ref": "#/$defs/ServiceLevelAgreementProperty" - } - } - }, - "required": ["version", "kind", "uuid", "type", "status", "dataset", "datasetName", "quantumName"], - "$defs": { - "Dataset": { - "type": "object", - "properties": { - "table": { - "type": "string", - "description": "Name of the table being cataloged; the value should only contain the table name. Do not include the project or dataset name in the value." - }, - "physicalName": { - "type": "string", - "description": "Physical name of the table, default value is table name + version separated by underscores, as `table_1_2_0`.", - "examples": ["table_1_2_0"] - }, - "priorTableName": { - "type": "string", - "description": "Name of the previous version of the dataset, if applicable." - }, - "description": { - "type": "string", - "description": "Description of the dataset." - }, - "authoritativeDefinitions": { - "$ref": "#/$defs/AuthoritativeDefinitions" - }, - "dataGranularity": { - "type": "string", - "description": "Granular level of the data in the table. Example would be `pmt_txn_id`.", - "examples": ["pmt_txn_id"] - }, - "columns": { - "type": "array", - "description": "Array. A list of columns in the table.", - "items": { - "$ref": "#/$defs/Column" - } - }, - "quality": { - "type": "array", - "description": "Data quality rules with all the relevant information for rule setup and execution.", - "items": { - "$ref": "#/$defs/DataQuality" - } - } - }, - "required": ["table"] - }, - "Column": { - "type": "object", - "properties": { - "column": { - "type": "string", - "description": "The name of the column." - }, - "isPrimaryKey": { - "type": "boolean", - "description": "Boolean value specifying whether the column is primary or not. Default is false." - }, - "primaryKeyPosition": { - "type": "integer", - "default": -1, - "description": "If column is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1." - }, - "businessName": { - "type": "string", - "description": "The business name of the column." - }, - "logicalType": { - "type": "string", - "description": "The logical column data type.", - "enum": ["string", "date", "number", "integer", "object", "array", "boolean"] - }, - "logicalTypeOptions": { - "type": "object", - "description": "Additional optional metadata to describe the logical type." - }, - "physicalType": { - "type": "string", - "description": "The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT." - }, - "description": { - "type": "string", - "description": "Description of the column." - }, - "isNullable": { - "type": "boolean", - "default": false, - "description": "Indicates if the column may contain Null values; possible values are true and false. Default is false." - }, - "isUnique": { - "type": "boolean", - "default": false, - "description": "Indicates if the column contains unique values; possible values are true and false. Default is false." - }, - "partitionStatus": { - "type": "boolean", - "default": false, - "description": "Indicates if the column is partitioned; possible values are true and false." - }, - "partitionKeyPosition": { - "type": "integer", - "default": -1, - "description": "If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1." - }, - "clusterStatus": { - "type": "boolean", - "default": false, - "description": "Indicates of the column is clustered; possible values are true and false." - }, - "clusterKeyPosition": { - "type": "integer", - "default": -1, - "description": "If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1." - }, - "classification": { - "type": "string", - "description": "Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5.", - "examples": ["confidential", "restricted", "public"] - }, - "authoritativeDefinitions": { - "$ref": "#/$defs/AuthoritativeDefinitions" - }, - "encryptedColumnName": { - "type": "string", - "description": "The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`." - }, - "transformSourceTables": { - "type": "array", - "description": "List of sources used in column transformation.", - "items": { - "type": "string" - } - }, - "transformLogic": { - "type": "string", - "description": "Logic used in the column transformation." - }, - "transformDescription": { - "type": "string", - "description": "Describes the transform logic in very simple terms." - }, - "sampleValues": { - "type": "array", - "description": "List of sample column values.", - "items": { - "type": "string" - } - }, - "criticalDataElementStatus": { - "type": "boolean", - "default": false, - "description": "True or false indicator; If element is considered a critical data element (CDE) then true else false." - }, - "tags": { - "type": "array", - "description": "A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level.", - "items": { - "type": "string" - } - } - }, - "allOf": [ - { - "if": { - "properties": { - "logicalType": { - "const": "string" - } - } - }, - "then": { - "properties": { - "logicalTypeOptions": { - "properties": { - "minLength": { - "type": "integer", - "minimum": 0, - "description": "Minimum length of the string." - }, - "maxLength": { - "type": "integer", - "minimum": 0, - "description": "Maximum length of the string." - }, - "pattern": { - "type": "string", - "format": "regex", - "description": "Regular expression pattern to define valid value. Follows regular expression syntax from ECMA-262 (https://262.ecma-international.org/5.1/#sec-15.10.1)." - }, - "format": { - "type": "string", - "examples": ["password", "byte", "binary", "email", "uuid", "uri", "hostname", "ipv4", "ipv6"], - "description": "Provides extra context about what format the string follows." - } - }, - "additionalProperties": false - } - } - } - }, { - "if": { - "properties": { - "logicalType": { - "const": "date" - } - } - }, - "then": { - "properties": { - "logicalTypeOptions": { - "properties": { - "format": { - "type": "string", - "examples": ["yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "HH:mm:ss"], - "description": "Format of the date. Follows the format as prescribed by [JDK DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). For example, format 'yyyy-MM-dd'." - }, - "exclusiveMaximum": { - "type": "boolean", - "default": false, - "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." - }, - "maximum": { - "type": "string", - "description": "All date values are less than or equal to this value (values <= maximum)." - }, - "exclusiveMinimum": { - "type": "boolean", - "default": false, - "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." - }, - "minimum": { - "type": "string", - "description": "All date values are greater than or equal to this value (values >= minimum)." - } - }, - "additionalProperties": false - } - } - } - }, - { - "if": { - "anyOf": [ - { - "properties": { - "logicalType": { - "const": "integer" - } - } - } - ] - }, - "then": { - "properties": { - "logicalTypeOptions": { - "properties": { - "multipleOf": { - "type": "number", - "exclusiveMinimum": 0, - "description": "Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5." - }, - "maximum": { - "type": "number", - "description": "All values are less than or equal to this value (values <= maximum)." - }, - "exclusiveMaximum": { - "type": "boolean", - "default": false, - "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." - }, - "minimum": { - "type": "number", - "description": "All values are greater than or equal to this value (values >= minimum)." - }, - "exclusiveMinimum": { - "type": "boolean", - "default": false, - "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." - }, - "format": { - "type": "string", - "default": "i32", - "description": "Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types).", - "enum": ["i8", "i16", "i32", "i64", "i128", "u8", "u16", "u32", "u64", "u128"] - } - }, - "additionalProperties": false - } - } - } - }, - { - "if": { - "anyOf": [ - { - "properties": { - "logicalType": { - "const": "number" - } - } - } - ] - }, - "then": { - "properties": { - "logicalTypeOptions": { - "properties": { - "multipleOf": { - "type": "number", - "exclusiveMinimum": 0, - "description": "Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5." - }, - "maximum": { - "type": "number", - "description": "All values are less than or equal to this value (values <= maximum)." - }, - "exclusiveMaximum": { - "type": "boolean", - "default": false, - "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." - }, - "minimum": { - "type": "number", - "description": "All values are greater than or equal to this value (values >= minimum)." - }, - "exclusiveMinimum": { - "type": "boolean", - "default": false, - "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." - }, - "format": { - "type": "string", - "default": "i32", - "description": "Format of the value in terms of how many bits of space it can use (follows the Rust float types).", - "enum": ["f32", "f64"] - } - }, - "additionalProperties": false - } - } - } - }, - { - "if": { - "properties": { - "logicalType": { - "const": "object" - } - } - }, - "then": { - "properties": { - "logicalTypeOptions": { - "properties": { - "maxProperties": { - "type": "integer", - "minimum": 0, - "description": "Maximum number of properties." - }, - "minProperties": { - "type": "integer", - "minimum": 0, - "default": 0, - "description": "Minimum number of properties." - }, - "required": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1, - "uniqueItems": true, - "description": "Property names that are required to exist in the object." - } - }, - "additionalProperties": false - } - } - } - }, - { - "if": { - "properties": { - "logicalType": { - "const": "array" - } - } - }, - "then": { - "properties": { - "logicalTypeOptions": { - "properties": { - "maxItems": { - "type": "integer", - "minimum": 0, - "description": "Maximum number of items." - }, - "minItems": { - "type": "integer", - "minimum": 0, - "default": 0, - "description": "Minimum number of items" - }, - "uniqueItems": { - "type": "boolean", - "default": false, - "description": "If set to true, all items in the array are unique." - } - }, - "additionalProperties": false - } - } - } - } - ], - "required": ["column", "logicalType", "physicalType"] - }, - "DataQuality": { - "type": "object", - "properties": { - "code": { - "type": "string", - "description": "The Rosewall data quality code(s) indicating which quality checks need to be performed at the dataset, table or column level; The quality keyword may appear at any level; Some quality checks require parameters such so the check can be completed (eg, list of fields used to identify a distinct row) therefore some quality checks may be followed by a single value or an array; See appendix for link to quality checks." - }, - "templateName": { - "type": "string", - "description": "The template name which indicates what is the equivalent template from the tool." - }, - "description": { - "type": "string", - "description": "Describe the quality check to be completed." - }, - "toolName": { - "type": "string", - "description": "Name of the tool used to complete the quality check; Most will be Elevate initially." - }, - "toolRuleName": { - "type": "string", - "description": "Name of the quality tool's rule created to complete the quality check." - }, - "dimension": { - "type": "string", - "description": "The key performance indicator (KPI) or dimension for data quality." - }, - "columns": { - "type": "string", - "description": "List of columns to be used in the quality check." - }, - "column": { - "type": "string", - "description": "To be used in lieu of quality.columns when only a single column is required for the quality check." - }, - "type": { - "type": "string", - "description": "The type of quality check." - }, - "severity": { - "type": "string", - "description": "The severance of the quality rule." - }, - "businessImpact": { - "type": "string", - "description": "Consequences of the rule failure." - }, - "scheduleCronExpression": { - "type": "string", - "description": "Rule execution schedule details." - }, - "customProperties": { - "type": "array", - "description": "Additional properties required for rule execution.", - "items": { - "$ref": "#/$defs/CustomProperty" - } - } - }, - "required": ["templateName", "toolName"] - }, - "AuthoritativeDefinitions": { - "type": "array", - "description": "List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", - "items": { - "type": "object", - "properties": { - "url": { - "type": "string", - "description": "URL to the authority." - }, - "type": { - "type": "string", - "description": "Type of definition for authority: v2.3 adds standard values: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`.", - "examples": ["businessDefinition", "transformationImplementation", "videoTutorial", "tutorial", "implementation"] - } - }, - "required": ["url", "type"] - } - }, - "Pricing": { - "type": "object", - "properties": { - "priceAmount": { - "type": "number", - "description": "Subscription price per unit of measure in `priceUnit`." - }, - "priceCurrency": { - "type": "string", - "description": "Currency of the subscription price in `price.priceAmount`." - }, - "priceUnit": { - "type": "string", - "description": "The unit of measure for calculating cost. Examples megabyte, gigabyte." - } - } - }, - "Stakeholder": { - "type": "object", - "properties": { - "username": { - "type": "string", - "description": "The stakeholder's username or email." - }, - "role": { - "type": "string", - "description": "The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role." - }, - "dateIn": { - "type": "string", - "description": "The date when the user became a stakeholder." - }, - "dateOut": { - "type": "string", - "description": "The date when the user ceased to be a stakeholder" - }, - "replacedByUsername": { - "type": "string", - "description": "The username of the user who replaced the stakeholder" - } - } - }, - "Role": { - "type": "object", - "properties": { - "role": { - "type": "string", - "description": "Name of the IAM role that provides access to the dataset; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." - }, - "access": { - "type": "string", - "description": "The type of access provided by the IAM role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." - }, - "firstLevelApprovers": { - "type": "string", - "description": "The name(s) of the first level approver(s) of the role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." - }, - "secondLevelApprovers": { - "type": "string", - "description": "The name(s) of the second level approver(s) of the role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." - } - }, - "required": ["role", "access"] - }, - "ServiceLevelAgreementProperty": { - "type": "object", - "properties": { - "property": { - "type": "string", - "description": "Specific property in SLA, check the periodic table. May requires units (more details to come)." - }, - "value": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ], - "description": "Agreement value. The label will change based on the property itself." - }, - "valueExt": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ], - "description": "Extended agreement value. The label will change based on the property itself." - }, - "unit": { - "type": "string", - "description": "**d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard." - }, - "column": { - "type": "string", - "description": "Column(s) to check on. Multiple columns should be extremely rare and, if so, separated by commas." - }, - "driver": { - "type": "string", - "description": "Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`.", - "examples": ["regulatory", "analytics", "operational"] - } - }, - "required": ["property", "value"] - }, - "CustomProperty": { - "type": "object", - "properties": { - "property": { - "type": "string", - "description": "The name of the key. Names should be in camel case–the same as if they were permanent properties in the contract." - }, - "value": { - "type": "object", - "description": "The value of the key." - } - } - } - } -} \ No newline at end of file +XXX REPLACE WITH FINAL v3.0.0 XXX From 3f83f91114438f77e15d88eef2b38acc3a07f17b Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 30 Jul 2024 09:23:57 -0400 Subject: [PATCH 15/93] RFC 6 --- CHANGELOG.md | 57 ++++++++++++++++++++++++------------------------ docs/standard.md | 53 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34c278e..4189cd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,28 +8,29 @@ This document tracks the history and evolution of the **Open Data Contract Stand # v3.0.0 - 2024-xx-xx - IN PROGRESS -* Fundamentals: - * Rename uuid to id - * Add name - * Rename quantumName to dataProduct and make it optional - * Rename datasetDomain to domain (we avoid the dataset prefix) - * Drop datasetKind (example: virtualDataset, was optional, have not seen any * usage) - * Drop userConsumptionMode (examples: analytical, was optional, already * deprecated in v2.) - * Drop sourceSystem (example: bigQuery, information will be encoded in servers) - * Drop sourcePlatform (example: googleCloudPlatform, information will be encoded * in servers) - * Drop productSlackChannel (will move to support channels) - * Drop productFeedbackUrl (will move to support channels) - * Drop productDl (will move to support channels) - * Drop username (credentials should not be stored in the data contract) - * Drop password (credentials should not be stored in the data contract) - * Drop driverVersion (will move to servers if needed) - * Drop driver (will move to servers if needed) - * Drop server (will move to servers if needed) - * Drop project (BigQuery-specific, will move to servers) - * Drop datasetName (BigQuery-specific, will move to servers) - * Drop database (BigQuery-specific, will move to servers) - * Drop schedulerAppName (not part of the contract) -* Schema: +* **New section**: Communication channels. +* **Changes** to fundamentals : + * Rename `uuid` to `id`. + * Add `name`. + * Rename `quantumName` to `dataProduct` and make it optional. + * Rename `datasetDomain` to `domain` (we avoid the dataset prefix). + * Drop `datasetKind` (example: `virtualDataset`, was optional, have not seen any usage). + * Drop `userConsumptionMode` (examples: `analytical`, was optional, already deprecated in v2.). + * Drop `sourceSystem` (example: `bigQuery`, information will be encoded in servers). + * Drop `sourcePlatform` (example: `googleCloudPlatform`, information will be encoded in servers). + * Drop `productSlackChannel` (will move to support channels). + * Drop `productFeedbackUrl` (will move to support channels). + * Drop `productDl` (will move to support channels). + * Drop `username` (credentials should not be stored in the data contract). + * Drop `password` (credentials should not be stored in the data contract). + * Drop `driverVersion` (will move to servers if needed). + * Drop `driver` (will move to servers if needed). + * Drop `server` (will move to servers if needed). + * Drop `project` (BigQuery-specific, will move to servers). + * Drop `datasetName` (BigQuery-specific, will move to servers). + * Drop `database` (BigQuery-specific, will move to servers). + * Drop `schedulerAppName` (not part of the contract). +* **Changes** to Schema: * Major changes, check spec. * Adds support for non table formats, hierarchies, and arrays. * `priorTableName` is not supported anymore, if needed, consider a custom property. @@ -46,23 +47,23 @@ This document tracks the history and evolution of the **Open Data Contract Stand * 'clusterKeyPosition' is not supported anymore, if needed, consider a custom property. * Restrict `dataset.table.columns.column.logicalType` to be one of `string, date, number, integer, object, array, boolean` * Add `dataset.table.columns.column.logicalTypeOptions` -* Data Quality: - * +* **Changes** to Data Quality: + * TBD. * Pricing: * No changes. -* Team: +* **Changes** to team (fka stakeholders): * Replaces `stakeholders`. Content stays the same. -* Role: +* **Changes** to Role: * Added `description` * Changed `access` is not required anymore * Security: * No changes. -* SLA: +* **Changes** to SLA: * Starting with v3, the schema is not purely tables and columns, hence minor modifications: columns are now elements. * 'slaDefaultColumn' is now 'slaDefaultElement'. * 'column' is now 'element'. * Explicit reference to Data QoS. -* Custom and other properties: +* **Changes** to custom and other properties: * 'systemInstance' is not supported anymore, if needed, consider a custom property. diff --git a/docs/standard.md b/docs/standard.md index b6a1dd5..6a7301c 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -15,6 +15,7 @@ This document describes the keys and values expected in a YAML data contract, pe 1. [Fundamentals (fka demographics)](#fundamentals) 1. [Schema](#schema) 1. [Data quality](#data-quality) +1. [Communication channels]() 1. [Pricing](#pricing) 1. [Team](#team) 1. [Roles](#roles) @@ -394,6 +395,58 @@ schema: | quality.scheduleCronExpression | Schedule Expression | No | Rule execution schedule details. | | quality.customProperties | Custom Properties | No | Additional properties required for rule execution. | + +## Support & communication channels + + +### Examples + +```yaml +support: + - channel: channel-name-or-identifier # Simple Slack communication channel + url: https://aidaug.slack.com/archives/C05UZRSBKLY + - channel: channel-name-or-identifier # Simple distribution list + url: mailto:datacontract-ann@bitol.io +``` + +```yaml +support: + - channel: channel-name-or-identifier + tool: teams + scope: interactive + url: https://bitol.io/teams/channel/my-data-contract-interactive + - channel: channel-name-or-identifier + tool: teams + scope: announcements + url: https://bitol.io/teams/channel/my-data-contract-announcements + invitationUrl: https://bitol.io/teams/channel/my-data-contract-announcements-invit + - channel: channel-name-or-identifier-for-all-announcement + description: All announcement for all data contracts + tool: teams + scope: announcements + url: https://bitol.io/teams/channel/all-announcements + - channel: channel-name-or-identifier + tool: email + scope: announcements + url: mailto:datacontract-ann@bitol.io + - channel: channel-name-or-identifier + tool: ticket + url: https://bitol.io/ticket/my-product +``` + +### Definitions + +| Key | UX label | Required | Description | +|------------------------|--------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------| +| support | Support | No | Top level for support channels | +| support.channel | Channel | Yes | Channel name or identifier. | +| support.url | Channel URL | Yes | Access URL using normal [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax) (https, mailto, etc.). | +| support.description | Descripton | No | Description of the channel, free text. | +| support.tool | Tool | No | Name of the tool, value can be `email`, `slack`, `teams`, `discord`, `ticket`, or `other`. | +| support.scope | Scope | No | Scope can be: `interactive`, `announcements`, `issues`. | +| support.invitationUrl | Invitation URL | No | Some tools uses invitation URL for requesting or subscribing. Follows the [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax). | + + ## Pricing This section covers pricing when you bill your customer for using this data product. Pricing is experimental in v2.1.1 of the data contract. From 948a8f9e826dffc63f586cff8a3ebb0ef3678b0c Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 30 Jul 2024 11:11:18 -0400 Subject: [PATCH 16/93] Added explanation --- docs/img/elements-of-schema-odcs-v3.png | Bin 0 -> 133050 bytes docs/img/elements-of-schema-odcs-v3.svg | 195 ++++++++++++++++++++++++ docs/standard.md | 16 +- 3 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 docs/img/elements-of-schema-odcs-v3.png create mode 100644 docs/img/elements-of-schema-odcs-v3.svg diff --git a/docs/img/elements-of-schema-odcs-v3.png b/docs/img/elements-of-schema-odcs-v3.png new file mode 100644 index 0000000000000000000000000000000000000000..3f7dce839b4b2b228155641901ca2db97f6a106f GIT binary patch literal 133050 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 z�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

j9$OoxrzAGIZKqMxL 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 onS>8_=l_5G|HJbCW;nb + + + + + 2♠︎ - + + + Backgound + + + + + + Layer 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + logicalType: object + physicalType: table + name: Orders + physicalName: order + + + + + logicalType: object + physicalType: table + name: OrdersLines + physicalName: or_line + + + + + logicalType: number + physicalType: float(10) + name: Quantity + physicalName: qty + + + + + logicalType: integer + physicalType: serial + name: Id + physicalName: id + + + + + properties + + + + + + + + + + + + elements + + + + + + + + + + + objects + + + + + + Orders + + + + + + OrderLines + + + + + + date + + + + + + customer_id + + + + + + delivery_ctry + + + + + + + + + + + + id + + + + + + id + + + + + + order_id + + + + + + qty + + + + + + product_id + + + + + + + + + + + diff --git a/docs/standard.md b/docs/standard.md index 6a7301c..21c7e64 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -81,7 +81,19 @@ tags: null ## Schema -This section describes the schema of the data contract. It is the support for data quality, which is detailed in the next section. Schema supports both a business representation of +This section describes the schema of the data contract. It is the support for data quality, which is detailed in the next section. Schema supports both a business representation of your data and a physical implementation. It allows to tie them together. + +In ODCS v3, the schema has evolved from the table and column representation, therefore the schema introduces a new terminology: + +* **Objects** are a structure of data: a table in a RDBMS system, a document in a NoSQL database, and so on. +* **Properties** are attributes of an object: a column in a table, a field in a payload, and so on. +* **Elements** are either an object or a property. + +Figure 1 illustrates those terms with a basic relational database. + + + +*Figure 1: elements of the schema in ODCS v3.* ### Examples @@ -397,7 +409,7 @@ schema: ## Support & communication channels - +Support and communication channels help consumers find help regarding their use of the data contract. In version 3, ODCS opens the ### Examples From c54ff406bcbac16ae33c593611a6fe06f1baf860 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 30 Jul 2024 15:07:40 -0400 Subject: [PATCH 17/93] Update CHANGELOG.md --- CHANGELOG.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4189cd4..3062534 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,16 +37,16 @@ This document tracks the history and evolution of the **Open Data Contract Stand * `dataGranularity` is now `dataGranularityDescription`. * `encryptedColumnName`is now `encryptedName`. * `partitionStatus` is now `partitioned`. - * 'clusterStatus' is not supported anymore, if needed, consider a custom property. - * 'clusterKeyPosition' is not supported anymore, if needed, consider a custom property. - * 'sampleValues' is now 'examples'. - * 'isNullable' is now 'required'. - * 'isUnique' is now 'unique'. - * 'isPrimaryKey' is now 'primaryKey'. - * 'criticalDataElementStatus' is now 'criticalDataElement'. - * 'clusterKeyPosition' is not supported anymore, if needed, consider a custom property. - * Restrict `dataset.table.columns.column.logicalType` to be one of `string, date, number, integer, object, array, boolean` - * Add `dataset.table.columns.column.logicalTypeOptions` + * `clusterStatus` is not supported anymore, if needed, consider a custom property. + * `clusterKeyPosition` is not supported anymore, if needed, consider a custom property. + * `sampleValues` is now `examples`. + * `isNullable` is now `required`. + * `isUnique` is now `unique`. + * `isPrimaryKey` is now `primaryKey`. + * `criticalDataElementStatus` is now `criticalDataElement`. + * `clusterKeyPosition` is not supported anymore, if needed, consider a custom property. + * Restrict `dataset.table.columns.column.logicalType` to be one of `string`, `date`, `number`, `integer`, `object`, `array`, `boolean`. + * Add `dataset.table.columns.column.logicalTypeOptions`. * **Changes** to Data Quality: * TBD. * Pricing: @@ -60,11 +60,11 @@ This document tracks the history and evolution of the **Open Data Contract Stand * No changes. * **Changes** to SLA: * Starting with v3, the schema is not purely tables and columns, hence minor modifications: columns are now elements. - * 'slaDefaultColumn' is now 'slaDefaultElement'. - * 'column' is now 'element'. + * `slaDefaultColumn` is now `slaDefaultElement`. + * `column` is now `element`. * Explicit reference to Data QoS. * **Changes** to custom and other properties: - * 'systemInstance' is not supported anymore, if needed, consider a custom property. + * `systemInstance` is not supported anymore, if needed, consider a custom property. # v2.2.2 - 2024-05-23 - APPROVED From 162dec0f41c2ab8d71f59c9b0ed510a41001bf80 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 30 Jul 2024 15:14:20 -0400 Subject: [PATCH 18/93] Update Signed-off-by: jgp --- CHANGELOG.md | 2 +- docs/standard.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3062534..4c0e489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ This document tracks the history and evolution of the **Open Data Contract Stand # v3.0.0 - 2024-xx-xx - IN PROGRESS -* **New section**: Communication channels. +* **New section**: Support & communication channels. * **Changes** to fundamentals : * Rename `uuid` to `id`. * Add `name`. diff --git a/docs/standard.md b/docs/standard.md index 21c7e64..907c0de 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -15,12 +15,12 @@ This document describes the keys and values expected in a YAML data contract, pe 1. [Fundamentals (fka demographics)](#fundamentals) 1. [Schema](#schema) 1. [Data quality](#data-quality) -1. [Communication channels]() +1. [Support & communication channels](#support) 1. [Pricing](#pricing) 1. [Team](#team) 1. [Roles](#roles) -1. [Service-level agreement](#service-level-agreement) -1. [Infrastructures & servers]() +1. [Service-level agreement](#sla) +1. [Infrastructures & servers](#servers) 1. [Custom & other properties](#custom-properties) 1. [Examples](#full-example) @@ -80,7 +80,7 @@ tags: null | description.usage | Usage | No | How to use the data. | -## Schema +## Schema {#schema} This section describes the schema of the data contract. It is the support for data quality, which is detailed in the next section. Schema supports both a business representation of your data and a physical implementation. It allows to tie them together. In ODCS v3, the schema has evolved from the table and column representation, therefore the schema introduces a new terminology: From 74c6670a377cd00c7577c6ba993860f643d95ac1 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 30 Jul 2024 15:21:07 -0400 Subject: [PATCH 19/93] Link issue in TOC --- docs/standard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard.md b/docs/standard.md index 907c0de..d696eb7 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -80,7 +80,7 @@ tags: null | description.usage | Usage | No | How to use the data. | -## Schema {#schema} +## Schema This section describes the schema of the data contract. It is the support for data quality, which is detailed in the next section. Schema supports both a business representation of your data and a physical implementation. It allows to tie them together. In ODCS v3, the schema has evolved from the table and column representation, therefore the schema introduces a new terminology: From 28752e82b046c64d9870ba7c53cb2b7ed7d9107a Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 30 Jul 2024 15:24:15 -0400 Subject: [PATCH 20/93] Update standard.md Fixed issues with TOC --- docs/standard.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/standard.md b/docs/standard.md index d696eb7..a00b212 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -7,7 +7,7 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color # Open Data Contract Standard ## Executive Summary -This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. It is divided in multiple sections: [fundamentals (fka demographics)](#fundamentals), [schema](#schema), [data quality](#data-quality), [pricing](#pricing), [team](#team), [roles](#roles), [service-level agreement](#service-level-agreement), and [other/custom properties](#custom-properties). Each section starts with at least an example followed by definition of each field/key. +This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. It is divided in multiple sections: [fundamentals (fka demographics)](#fundamentals), [schema](#schema), [data quality](#data-quality), [pricing](#pricing), [team](#team), [roles](#roles), [service-level agreement](#sla), and [other/custom properties](#custom-properties). Each section starts with at least an example followed by definition of each field/key. ## Table of content @@ -408,7 +408,7 @@ schema: | quality.customProperties | Custom Properties | No | Additional properties required for rule execution. | -## Support & communication channels +## Support & communication channels Support and communication channels help consumers find help regarding their use of the data contract. In version 3, ODCS opens the ### Examples @@ -551,7 +551,7 @@ roles: | roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role. | -## Service-Level Agreement (SLA) +## Service-Level Agreement (SLA) This section describes the service-level agreements (SLA). * Use the `Table.Column` to indicate the number to do the checks on, as in `SELECT txn_ref_dt FROM tab1`. @@ -608,7 +608,7 @@ slaProperties: ## Infrastructure & servers TBD -## Custom Properties +## Custom Properties This section covers custom properties you may find in a data contract. ### Example From 9eb9add1bcb73cd07feb4698fe4a0383a03ccfb8 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Thu, 15 Aug 2024 15:38:27 +0800 Subject: [PATCH 21/93] Update JSON Schema according to RFCs 0001, 0002, 0003, 0004, 0005 and 0006, update examples to be compliant with latest v3 schema, add in Github action to validate examples --- .github/workflows/validate-examples.yaml | 18 + CHANGELOG.md | 5 + docs/examples/all/full-example.odcs.yaml | 127 +- ...stgresql-adventureworks-contract.odcs.yaml | 6216 ++++++++--------- .../data-types/all-data-types.odcs.yaml | 39 +- .../table-column-description.odcs.yaml | 18 +- .../quality/column-accuracy.odcs.yaml | 19 +- .../quality/column-completeness.odcs.yaml | 19 +- .../quality/column-validity.odcs.yaml | 19 +- .../service-and-operational-roles.odcs.yaml | 9 +- .../schema/all-schema-types.odcs.yaml | 103 + docs/examples/schema/table-column.odcs.yaml | 15 +- .../table-columns-with-partition.odcs.yaml | 74 +- docs/examples/server/azure-server.odcs.yaml | 10 + .../examples/sla/database-table-sla.odcs.yaml | 17 +- .../stakeholders/basic-four-dpo.odcs.yaml | 25 +- docs/standard.md | 139 +- schema/odcs-json-schema-v3.0.0.json | 1779 ++++- script/validate-examples.sh | 35 + 19 files changed, 4845 insertions(+), 3841 deletions(-) create mode 100644 .github/workflows/validate-examples.yaml create mode 100644 docs/examples/schema/all-schema-types.odcs.yaml create mode 100644 docs/examples/server/azure-server.odcs.yaml create mode 100644 script/validate-examples.sh diff --git a/.github/workflows/validate-examples.yaml b/.github/workflows/validate-examples.yaml new file mode 100644 index 0000000..36243e6 --- /dev/null +++ b/.github/workflows/validate-examples.yaml @@ -0,0 +1,18 @@ +name: validate-examples +on: + push: + branches: ["*"] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: latest + - name: Install ajv + run: | + npm i -g ajv-cli ajv-formats + - name: Validate examples + run: bash script/validate-examples.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c0e489..6c2ce9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,11 @@ This document tracks the history and evolution of the **Open Data Contract Stand * **Changes** to Schema: * Major changes, check spec. * Adds support for non table formats, hierarchies, and arrays. + * `name` is a new field + * `items` is a new field * `priorTableName` is not supported anymore, if needed, consider a custom property. + * `table` is not supported anymore, if needed, consider using `name`. + * `columns` is now `properties` * `dataGranularity` is now `dataGranularityDescription`. * `encryptedColumnName`is now `encryptedName`. * `partitionStatus` is now `partitioned`. @@ -45,6 +49,7 @@ This document tracks the history and evolution of the **Open Data Contract Stand * `isPrimaryKey` is now `primaryKey`. * `criticalDataElementStatus` is now `criticalDataElement`. * `clusterKeyPosition` is not supported anymore, if needed, consider a custom property. + * `transformSourceTables` is now `transformSourceObjects` * Restrict `dataset.table.columns.column.logicalType` to be one of `string`, `date`, `number`, `integer`, `object`, `array`, `boolean`. * Add `dataset.table.columns.column.logicalTypeOptions`. * **Changes** to Data Quality: diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index a9db806..e13f00d 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -1,10 +1,9 @@ # What's this data contract about? -datasetDomain: seller # Domain -quantumName: my quantum # Data product name -userConsumptionMode: Analytical +domain: seller # Domain +dataProduct: my quantum # Data product name version: 1.1.0 # Version (follows semantic versioning) status: current -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a # Lots of information description: @@ -13,98 +12,79 @@ description: usage: Predict sales over time tenant: ClimateQuantumInc -# Getting support -productDl: product-dl@ClimateQuantum.org -productSlackChannel: '#product-help' -productFeedbackUrl: https://product-feedback.com/sellers - -# Physical parts / GCP / BigQuery specific -sourcePlatform: googleCloudPlatform -sourceSystem: bigQuery -datasetProject: edw # BQ dataset -datasetName: access_views # BQ dataset - kind: DataContract -apiVersion: v2.2.2 # Standard version (follows semantic versioning, previously known as templateVersion) +apiVersion: v3.0.0 # Standard version (follows semantic versioning, previously known as templateVersion) type: tables -# Physical access -driver: jdbc:postgresql -driverVersion: 1.0.0 -server: localhost:5432 -database: pypl-edw.pp_access_views -username: '${env.username}' -password: '${env.password}' -schedulerAppName: name_coming_from_scheduler # NEW 2.1.0 Required if you want to schedule stuff, comes from DataALM. +servers: + - server: my-postgres + type: postgres + host: localhost + port: 5432 + database: pypl-edw + schema: pp_access_views # Dataset, schema and quality -dataset: - - table: tbl - physicalName: tbl_1 # NEW in v2.1.0, Optional, default value is table name + version separated by underscores, as table_1_2_0 - priorTableName: seller_table # if needed +schema: + - name: tbl + physicalName: tbl_1 description: Provides core payment metrics - authoritativeDefinitions: # NEW in v2.2.0, inspired by the column-level authoritative links + authoritativeDefinitions: - url: https://catalog.data.gov/dataset/air-quality type: businessDefinition - url: https://youtu.be/jbY1BKFj9ec type: videoTutorial - tags: null - dataGranularity: Aggregation on columns txn_ref_dt, pmt_txn_id - columns: - - column: txn_ref_dt - isPrimaryKey: false # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. + tags: [ ] + dataGranularityDescription: Aggregation on columns txn_ref_dt, pmt_txn_id + properties: + - name: txn_ref_dt + primaryKey: false primaryKeyPosition: -1 businessName: transaction reference date logicalType: date physicalType: date - isNullable: false + required: false description: Reference date for transaction - partitionStatus: true + partitioned: true partitionKeyPosition: 1 - clusterStatus: false - clusterKeyPosition: -1 - criticalDataElementStatus: false - tags: [] + criticalDataElement: false + tags: [ ] classification: public - transformSourceTables: + transformSourceObjects: - table_name_1 - table_name_2 - table_name_3 transformLogic: sel t1.txn_dt as txn_ref_dt from table_name_1 as t1, table_name_2 as t2, table_name_3 as t3 where t1.txn_dt=date-3 transformDescription: defines the logic in business terms; logic for dummies - sampleValues: - - 2022-10-03 - - 2020-01-28 - - column: rcvr_id - isPrimaryKey: true # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. + examples: + - "2022-10-03" + - "2020-01-28" + - name: rcvr_id + primaryKey: true primaryKeyPosition: 1 businessName: receiver id logicalType: string physicalType: varchar(18) - isNullable: false + required: false description: A description for column rcvr_id. - partitionStatus: false + partitioned: false partitionKeyPosition: -1 - clusterStatus: true - clusterKeyPosition: 1 - criticalDataElementStatus: false - tags: [] + criticalDataElement: false + tags: [ ] classification: restricted - - column: rcvr_cntry_code - isPrimaryKey: false # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. + - name: rcvr_cntry_code + primaryKey: false primaryKeyPosition: -1 businessName: receiver country code logicalType: string physicalType: varchar(2) - isNullable: false + required: false description: Country code - partitionStatus: false + partitioned: false partitionKeyPosition: -1 - clusterStatus: false - clusterKeyPosition: -1 - criticalDataElementStatus: false - tags: [] + criticalDataElement: false + tags: [ ] classification: public authoritativeDefinitions: - url: https://collibra.com/asset/742b358f-71a5-4ab1-bda4-dcdba9418c25 @@ -113,7 +93,7 @@ dataset: type: transformationImplementation - url: jdbc:postgresql://localhost:5432/adventureworks/tbl_1/rcvr_cntry_code type: implementation - encryptedColumnName: rcvr_cntry_code_encrypted + encryptedName: rcvr_cntry_code_encrypted quality: - code: nullCheck templateName: NullCheck @@ -150,20 +130,20 @@ price: priceCurrency: USD priceUnit: megabyte -# Stakeholders -stakeholders: +# Team +team: - username: ceastwood role: Data Scientist - dateIn: 2022-08-02 - dateOut: 2022-10-01 + dateIn: "2022-08-02" + dateOut: "2022-10-01" replacedByUsername: mhopper - username: mhopper role: Data Scientist - dateIn: 2022-10-01 + dateIn: "2022-10-01" - username: daustin role: Owner comment: Keeper of the grail - dateIn: 2022-10-01 + dateIn: "2022-10-01" # Roles roles: @@ -185,18 +165,18 @@ roles: secondLevelApprovers: 'mickey' # SLA -slaDefaultColumn: tab1.txn_ref_dt # Optional, default value is partitionColumn. +slaDefaultElement: tab1.txn_ref_dt slaProperties: - property: latency # Property, see list of values in DP QoS value: 4 unit: d # d, day, days for days; y, yr, years for years column: tab1.txn_ref_dt # This would not be needed as it is the same table.column as the default one - property: generalAvailability - value: 2022-05-12T09:30:10-08:00 + value: "2022-05-12T09:30:10-08:00" - property: endOfSupport - value: 2032-05-12T09:30:10-08:00 + value: "2032-05-12T09:30:10-08:00" - property: endOfLife - value: 2042-05-12T09:30:10-08:00 + value: "2042-05-12T09:30:10-08:00" - property: retention value: 3 unit: y @@ -226,7 +206,6 @@ customProperties: - property: somePropertyName value: property.value - property: dataprocClusterName # Used for specific applications like Elevate - value: [cluster name] + value: [ cluster name ] -systemInstance: instance.ClimateQuantum.org -contractCreatedTs: 2022-11-15 02:59:43 +contractCreatedTs: "2022-11-15T02:59:43+00:00" diff --git a/docs/examples/all/postgresql-adventureworks-contract.odcs.yaml b/docs/examples/all/postgresql-adventureworks-contract.odcs.yaml index 9092916..ba48a96 100644 --- a/docs/examples/all/postgresql-adventureworks-contract.odcs.yaml +++ b/docs/examples/all/postgresql-adventureworks-contract.odcs.yaml @@ -1,5719 +1,5257 @@ version: "1.0.0" -standardVersion: "2.2.0" -uuid: "6aeafdc1-ed62-4c8f-bf0a-da1061c98cdb" -username: "postgres" +apiVersion: "v3.0.0" +id: "6aeafdc1-ed62-4c8f-bf0a-da1061c98cdb" type: "tables" status: "Development" -server: "localhost" -kind: "managedDataset" -driverVersion: "42.6.0" -driver: "org.postgresql.Driver" +kind: "DataContract" description: {} -database: "adventureworks" -dataset: - tables: - - table: "department" +schema: + - name: "department" physicalName: "department" description: "Lookup table containing the departments within the Adventure Works\ \ Cycles company." - columns: - - column: "departmentid" - logicalType: "Numeric" + properties: + - name: "departmentid" + logicalType: "number" physicalType: "serial" description: "Primary key for Department records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/department/departmentid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Name of the department." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/department/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "groupname" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "groupname" + logicalType: "object" physicalType: "Name" description: "Name of the group to which the department belongs." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/department/groupname" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/department/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "employee" + criticalDataElement: false + primaryKey: false + required: false + - name: "employee" physicalName: "employee" description: "Employee information such as salary, department, and title." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key for Employee records. Foreign key to BusinessEntity.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "nationalidnumber" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "nationalidnumber" + logicalType: "string" physicalType: "varchar[15]" description: "Unique national identification number such as a social security\ \ number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/nationalidnumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "loginid" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "loginid" + logicalType: "string" physicalType: "varchar[256]" description: "Network login." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/loginid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "jobtitle" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "jobtitle" + logicalType: "string" physicalType: "varchar[50]" description: "Work title such as Buyer or Sales Representative." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/jobtitle" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "birthdate" - logicalType: "Date" + criticalDataElement: false + primaryKey: false + required: false + - name: "birthdate" + logicalType: "date" physicalType: "date" description: "Date of birth." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/birthdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "maritalstatus" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "maritalstatus" + logicalType: "string" physicalType: "bpchar" description: "M = Married, S = Single" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/maritalstatus" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "gender" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "gender" + logicalType: "string" physicalType: "bpchar" description: "M = Male, F = Female" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/gender" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "hiredate" - logicalType: "Date" + criticalDataElement: false + primaryKey: false + required: false + - name: "hiredate" + logicalType: "date" physicalType: "date" description: "Employee hired on this date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/hiredate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "salariedflag" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "salariedflag" + logicalType: "object" physicalType: "Flag" description: "Job classification. 0 = Hourly, not exempt from collective bargaining.\ \ 1 = Salaried, exempt from collective bargaining." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/salariedflag" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "vacationhours" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "vacationhours" + logicalType: "number" physicalType: "int2" description: "Number of available vacation hours." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/vacationhours" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "sickleavehours" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "sickleavehours" + logicalType: "number" physicalType: "int2" description: "Number of available sick leave hours." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/sickleavehours" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "currentflag" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "currentflag" + logicalType: "object" physicalType: "Flag" description: "0 = Inactive, 1 = Active" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/currentflag" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "organizationnode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "organizationnode" + logicalType: "string" physicalType: "varchar[2147483647]" description: "Where the employee is located in corporate hierarchy." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employee/organizationnode" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "employeedepartmenthistory" + criticalDataElement: false + primaryKey: false + required: false + - name: "employeedepartmenthistory" physicalName: "employeedepartmenthistory" description: "Employee department transfers." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Employee identification number. Foreign key to Employee.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeedepartmenthistory/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "departmentid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "departmentid" + logicalType: "number" physicalType: "int2" description: "Department in which the employee worked including currently. Foreign\ \ key to Department.DepartmentID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeedepartmenthistory/departmentid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "shiftid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "shiftid" + logicalType: "number" physicalType: "int2" description: "Identifies which 8-hour shift the employee works. Foreign key\ \ to Shift.Shift.ID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeedepartmenthistory/shiftid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "startdate" - logicalType: "Date" + criticalDataElement: false + primaryKey: true + required: false + - name: "startdate" + logicalType: "date" physicalType: "date" description: "Date the employee started work in the department." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeedepartmenthistory/startdate" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "enddate" - logicalType: "Date" + criticalDataElement: false + primaryKey: true + required: false + - name: "enddate" + logicalType: "date" physicalType: "date" description: "Date the employee left the department. NULL = Current department." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeedepartmenthistory/enddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeedepartmenthistory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "employeepayhistory" + criticalDataElement: false + primaryKey: false + required: false + - name: "employeepayhistory" physicalName: "employeepayhistory" description: "Employee pay history." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Employee identification number. Foreign key to Employee.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeepayhistory/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "ratechangedate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "ratechangedate" + logicalType: "date" physicalType: "timestamp" description: "Date the change in pay is effective" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeepayhistory/ratechangedate" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "rate" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "rate" + logicalType: "number" physicalType: "numeric" description: "Salary hourly rate." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeepayhistory/rate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "payfrequency" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "payfrequency" + logicalType: "number" physicalType: "int2" description: "1 = Salary received monthly, 2 = Salary received biweekly" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeepayhistory/payfrequency" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/employeepayhistory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "jobcandidate" + criticalDataElement: false + primaryKey: false + required: false + - name: "jobcandidate" physicalName: "jobcandidate" description: "Résumés submitted to Human Resources by job applicants." - columns: - - column: "jobcandidateid" - logicalType: "Numeric" + properties: + - name: "jobcandidateid" + logicalType: "number" physicalType: "serial" description: "Primary key for JobCandidate records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/jobcandidate/jobcandidateid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "businessentityid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Employee identification number if applicant was hired. Foreign\ \ key to Employee.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/jobcandidate/businessentityid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "resume" - logicalType: "XML" + criticalDataElement: false + primaryKey: false + required: false + - name: "resume" + logicalType: "string" physicalType: "xml" description: "Résumé in XML format." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/jobcandidate/resume" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/jobcandidate/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "shift" + criticalDataElement: false + primaryKey: false + required: false + - name: "shift" physicalName: "shift" description: "Work shift lookup table." - columns: - - column: "shiftid" - logicalType: "Numeric" + properties: + - name: "shiftid" + logicalType: "number" physicalType: "serial" description: "Primary key for Shift records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shift/shiftid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Shift description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shift/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "starttime" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "starttime" + logicalType: "date" physicalType: "time" description: "Shift start time." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shift/starttime" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "endtime" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "endtime" + logicalType: "date" physicalType: "time" description: "Shift end time." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shift/endtime" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shift/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "address" + criticalDataElement: false + primaryKey: false + required: false + - name: "address" physicalName: "address" description: "Street address information for customers, employees, and vendors." - columns: - - column: "addressid" - logicalType: "Numeric" + properties: + - name: "addressid" + logicalType: "number" physicalType: "serial" description: "Primary key for Address records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/addressid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "addressline1" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "addressline1" + logicalType: "string" physicalType: "varchar[60]" description: "First street address line." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/addressline1" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "addressline2" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "addressline2" + logicalType: "string" physicalType: "varchar[60]" description: "Second street address line." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/addressline2" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "city" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "city" + logicalType: "string" physicalType: "varchar[30]" description: "Name of the city." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/city" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "stateprovinceid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "stateprovinceid" + logicalType: "number" physicalType: "int4" description: "Unique identification number for the state or province. Foreign\ \ key to StateProvince table." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/stateprovinceid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "postalcode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "postalcode" + logicalType: "string" physicalType: "varchar[15]" description: "Postal code for the street address." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/postalcode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "spatiallocation" - logicalType: "Binary" + criticalDataElement: false + primaryKey: false + required: false + - name: "spatiallocation" + logicalType: "string" physicalType: "bytea" description: "Latitude and longitude of this address." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/spatiallocation" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/address/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "addresstype" + criticalDataElement: false + primaryKey: false + required: false + - name: "addresstype" physicalName: "addresstype" description: "Types of addresses stored in the Address table." - columns: - - column: "addresstypeid" - logicalType: "Numeric" + properties: + - name: "addresstypeid" + logicalType: "number" physicalType: "serial" description: "Primary key for AddressType records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/addresstype/addresstypeid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Address type description. For example, Billing, Home, or Shipping." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/addresstype/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/addresstype/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/addresstype/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "businessentity" + criticalDataElement: false + primaryKey: false + required: false + - name: "businessentity" physicalName: "businessentity" description: "Source of the ID that connects vendors, customers, and employees\ \ with address and contact information." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "serial" description: "Primary key for all customers, vendors, and employees." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentity/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: true + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentity/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentity/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "businessentityaddress" + criticalDataElement: false + primaryKey: false + required: false + - name: "businessentityaddress" physicalName: "businessentityaddress" description: "Cross-reference table mapping customers, vendors, and employees\ \ to their addresses." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to BusinessEntity.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentityaddress/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "addressid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "addressid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to Address.AddressID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentityaddress/addressid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "addresstypeid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "addresstypeid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to AddressType.AddressTypeID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentityaddress/addresstypeid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: true + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentityaddress/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentityaddress/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "businessentitycontact" + criticalDataElement: false + primaryKey: false + required: false + - name: "businessentitycontact" physicalName: "businessentitycontact" description: "Cross-reference table mapping stores, vendors, and employees to\ \ people" - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to BusinessEntity.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentitycontact/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "personid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "personid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to Person.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentitycontact/personid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "contacttypeid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "contacttypeid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to ContactType.ContactTypeID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentitycontact/contacttypeid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: true + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentitycontact/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/businessentitycontact/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "contacttype" + criticalDataElement: false + primaryKey: false + required: false + - name: "contacttype" physicalName: "contacttype" description: "Lookup table containing the types of business entity contacts." - columns: - - column: "contacttypeid" - logicalType: "Numeric" + properties: + - name: "contacttypeid" + logicalType: "number" physicalType: "serial" description: "Primary key for ContactType records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/contacttype/contacttypeid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Contact type description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/contacttype/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/contacttype/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "countryregion" + criticalDataElement: false + primaryKey: false + required: false + - name: "countryregion" physicalName: "countryregion" description: "Lookup table containing the ISO standard codes for countries and\ \ regions." - columns: - - column: "countryregioncode" - logicalType: "String" + properties: + - name: "countryregioncode" + logicalType: "string" physicalType: "varchar[3]" description: "ISO standard code for countries and regions." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/countryregion/countryregioncode" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Country or region name." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/countryregion/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/countryregion/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "emailaddress" + criticalDataElement: false + primaryKey: false + required: false + - name: "emailaddress" physicalName: "emailaddress" description: "Where to send a person email." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key. Person associated with this email address. Foreign\ \ key to Person.BusinessEntityID" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/emailaddress/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "emailaddressid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "emailaddressid" + logicalType: "number" physicalType: "serial" description: "Primary key. ID of this email address." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/emailaddress/emailaddressid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "emailaddress" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "emailaddress" + logicalType: "string" physicalType: "varchar[50]" description: "E-mail address for the person." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/emailaddress/emailaddress" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/emailaddress/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/emailaddress/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "password" + criticalDataElement: false + primaryKey: false + required: false + - name: "password" physicalName: "password" description: "One way hashed authentication information" - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/password/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "passwordhash" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "passwordhash" + logicalType: "string" physicalType: "varchar[128]" description: "Password for the e-mail account." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/password/passwordhash" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "passwordsalt" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "passwordsalt" + logicalType: "string" physicalType: "varchar[10]" description: "Random value concatenated with the password string before the\ \ password is hashed." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/password/passwordsalt" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/password/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/password/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "person" + criticalDataElement: false + primaryKey: false + required: false + - name: "person" physicalName: "person" description: "Human beings involved with AdventureWorks: employees, customer contacts,\ \ and vendor contacts." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key for Person records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "persontype" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "persontype" + logicalType: "string" physicalType: "bpchar" description: "Primary type of person: SC = Store Contact, IN = Individual (retail)\ \ customer, SP = Sales person, EM = Employee (non-sales), VC = Vendor contact,\ \ GC = General contact" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/persontype" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "namestyle" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "namestyle" + logicalType: "object" physicalType: "NameStyle" description: "0 = The data in FirstName and LastName are stored in western style\ \ (first name, last name) order. 1 = Eastern style (last name, first name)\ \ order." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/namestyle" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "title" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "title" + logicalType: "string" physicalType: "varchar[8]" description: "A courtesy title. For example, Mr. or Ms." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/title" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "firstname" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "firstname" + logicalType: "object" physicalType: "Name" description: "First name of the person." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/firstname" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "middlename" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "middlename" + logicalType: "object" physicalType: "Name" description: "Middle name or middle initial of the person." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/middlename" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "lastname" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "lastname" + logicalType: "object" physicalType: "Name" description: "Last name of the person." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/lastname" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "suffix" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "suffix" + logicalType: "string" physicalType: "varchar[10]" description: "Surname suffix. For example, Sr. or Jr." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/suffix" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "emailpromotion" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "emailpromotion" + logicalType: "number" physicalType: "int4" description: "0 = Contact does not wish to receive e-mail promotions, 1 = Contact\ \ does wish to receive e-mail promotions from AdventureWorks, 2 = Contact\ \ does wish to receive e-mail promotions from AdventureWorks and selected\ \ partners." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/emailpromotion" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "additionalcontactinfo" - logicalType: "XML" + criticalDataElement: false + primaryKey: false + required: false + - name: "additionalcontactinfo" + logicalType: "string" physicalType: "xml" description: "Additional contact information about the person stored in xml\ \ format." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/additionalcontactinfo" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "demographics" - logicalType: "XML" + criticalDataElement: false + primaryKey: false + required: false + - name: "demographics" + logicalType: "string" physicalType: "xml" description: "Personal information such as hobbies, and income collected from\ \ online shoppers. Used for sales analysis." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/demographics" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/person/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "personphone" + criticalDataElement: false + primaryKey: false + required: false + - name: "personphone" physicalName: "personphone" description: "Telephone number and type of a person." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Business entity identification number. Foreign key to Person.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/personphone/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "phonenumber" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "phonenumber" + logicalType: "object" physicalType: "Phone" description: "Telephone number identification number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/personphone/phonenumber" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "phonenumbertypeid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "phonenumbertypeid" + logicalType: "number" physicalType: "int4" description: "Kind of phone number. Foreign key to PhoneNumberType.PhoneNumberTypeID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/personphone/phonenumbertypeid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/personphone/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "phonenumbertype" + criticalDataElement: false + primaryKey: false + required: false + - name: "phonenumbertype" physicalName: "phonenumbertype" description: "Type of phone number of a person." - columns: - - column: "phonenumbertypeid" - logicalType: "Numeric" + properties: + - name: "phonenumbertypeid" + logicalType: "number" physicalType: "serial" description: "Primary key for telephone number type records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/phonenumbertype/phonenumbertypeid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Name of the telephone number type" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/phonenumbertype/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/phonenumbertype/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "stateprovince" + criticalDataElement: false + primaryKey: false + required: false + - name: "stateprovince" physicalName: "stateprovince" description: "State and province lookup table." - columns: - - column: "stateprovinceid" - logicalType: "Numeric" + properties: + - name: "stateprovinceid" + logicalType: "number" physicalType: "serial" description: "Primary key for StateProvince records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/stateprovince/stateprovinceid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "stateprovincecode" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "stateprovincecode" + logicalType: "string" physicalType: "bpchar" description: "ISO standard state or province code." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/stateprovince/stateprovincecode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "countryregioncode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "countryregioncode" + logicalType: "string" physicalType: "varchar[3]" description: "ISO standard country or region code. Foreign key to CountryRegion.CountryRegionCode." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/stateprovince/countryregioncode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "isonlystateprovinceflag" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "isonlystateprovinceflag" + logicalType: "object" physicalType: "Flag" description: "0 = StateProvinceCode exists. 1 = StateProvinceCode unavailable,\ \ using CountryRegionCode." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/stateprovince/isonlystateprovinceflag" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "State or province description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/stateprovince/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "territoryid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "territoryid" + logicalType: "number" physicalType: "int4" description: "ID of the territory in which the state or province is located.\ \ Foreign key to SalesTerritory.SalesTerritoryID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/stateprovince/territoryid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/stateprovince/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/stateprovince/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "billofmaterials" + criticalDataElement: false + primaryKey: false + required: false + - name: "billofmaterials" physicalName: "billofmaterials" description: "Items required to make bicycles and bicycle subassemblies. It identifies\ \ the heirarchical relationship between a parent product and its components." - columns: - - column: "billofmaterialsid" - logicalType: "Numeric" + properties: + - name: "billofmaterialsid" + logicalType: "number" physicalType: "serial" description: "Primary key for BillOfMaterials records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/billofmaterialsid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productassemblyid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productassemblyid" + logicalType: "number" physicalType: "int4" description: "Parent product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/productassemblyid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "componentid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "componentid" + logicalType: "number" physicalType: "int4" description: "Component identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/componentid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "startdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "startdate" + logicalType: "date" physicalType: "timestamp" description: "Date the component started being used in the assembly item." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/startdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "enddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "enddate" + logicalType: "date" physicalType: "timestamp" description: "Date the component stopped being used in the assembly item." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/enddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "unitmeasurecode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "unitmeasurecode" + logicalType: "string" physicalType: "bpchar" description: "Standard code identifying the unit of measure for the quantity." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/unitmeasurecode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "bomlevel" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "bomlevel" + logicalType: "number" physicalType: "int2" description: "Indicates the depth the component is from its parent (AssemblyID)." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/bomlevel" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "perassemblyqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "perassemblyqty" + logicalType: "number" physicalType: "numeric" description: "Quantity of the component needed to create the assembly." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/perassemblyqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/billofmaterials/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "culture" + criticalDataElement: false + primaryKey: false + required: false + - name: "culture" physicalName: "culture" description: "Lookup table containing the languages in which some AdventureWorks\ \ data is stored." - columns: - - column: "cultureid" - logicalType: "String" + properties: + - name: "cultureid" + logicalType: "string" physicalType: "bpchar" description: "Primary key for Culture records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/culture/cultureid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Culture description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/culture/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/culture/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "document" + criticalDataElement: false + primaryKey: false + required: false + - name: "document" physicalName: "document" description: "Product maintenance documents." - columns: - - column: "title" - logicalType: "String" + properties: + - name: "title" + logicalType: "string" physicalType: "varchar[50]" description: "Title of the document." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/title" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "owner" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "owner" + logicalType: "number" physicalType: "int4" description: "Employee who controls the document. Foreign key to Employee.BusinessEntityID" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/owner" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "folderflag" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "folderflag" + logicalType: "object" physicalType: "Flag" description: "0 = This is a folder, 1 = This is a document." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/folderflag" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "filename" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "filename" + logicalType: "string" physicalType: "varchar[400]" description: "File name of the document" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/filename" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "fileextension" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "fileextension" + logicalType: "string" physicalType: "varchar[8]" description: "File extension indicating the document type. For example, .doc\ \ or .txt." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/fileextension" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "revision" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "revision" + logicalType: "string" physicalType: "bpchar" description: "Revision number of the document." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/revision" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "changenumber" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "changenumber" + logicalType: "number" physicalType: "int4" description: "Engineering change approval number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/changenumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "status" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "status" + logicalType: "number" physicalType: "int2" description: "1 = Pending approval, 2 = Approved, 3 = Obsolete" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/status" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "documentsummary" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "documentsummary" + logicalType: "string" physicalType: "text" description: "Document abstract." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/documentsummary" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "document" - logicalType: "Binary" + criticalDataElement: false + primaryKey: false + required: false + - name: "document" + logicalType: "string" physicalType: "bytea" description: "Complete document." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/document" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" description: "ROWGUIDCOL number uniquely identifying the record. Required for\ \ FileStream." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "documentnode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "documentnode" + logicalType: "string" physicalType: "varchar[2147483647]" description: "Primary key for Document records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/document/documentnode" - criticalDataElementStatus: false - primary: true - nullable: false - - table: "illustration" + criticalDataElement: false + primaryKey: true + required: false + - name: "illustration" physicalName: "illustration" description: "Bicycle assembly diagrams." - columns: - - column: "illustrationid" - logicalType: "Numeric" + properties: + - name: "illustrationid" + logicalType: "number" physicalType: "serial" description: "Primary key for Illustration records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/illustration/illustrationid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "diagram" - logicalType: "XML" + criticalDataElement: false + primaryKey: true + required: false + - name: "diagram" + logicalType: "string" physicalType: "xml" description: "Illustrations used in manufacturing instructions. Stored as XML." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/illustration/diagram" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/illustration/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "location" + criticalDataElement: false + primaryKey: false + required: false + - name: "location" physicalName: "location" description: "Product inventory and manufacturing locations." - columns: - - column: "locationid" - logicalType: "Numeric" + properties: + - name: "locationid" + logicalType: "number" physicalType: "serial" description: "Primary key for Location records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/location/locationid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Location description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/location/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "costrate" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "costrate" + logicalType: "number" physicalType: "numeric" description: "Standard hourly cost of the manufacturing location." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/location/costrate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "availability" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "availability" + logicalType: "number" physicalType: "numeric" description: "Work capacity (in hours) of the manufacturing location." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/location/availability" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/location/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "product" + criticalDataElement: false + primaryKey: false + required: false + - name: "product" physicalName: "product" description: "Products sold or used in the manfacturing of sold products." - columns: - - column: "productid" - logicalType: "Numeric" + properties: + - name: "productid" + logicalType: "number" physicalType: "serial" description: "Primary key for Product records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Name of the product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "productnumber" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "productnumber" + logicalType: "string" physicalType: "varchar[25]" description: "Unique product identification number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/productnumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "makeflag" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "makeflag" + logicalType: "object" physicalType: "Flag" description: "0 = Product is purchased, 1 = Product is manufactured in-house." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/makeflag" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "finishedgoodsflag" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "finishedgoodsflag" + logicalType: "object" physicalType: "Flag" description: "0 = Product is not a salable item. 1 = Product is salable." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/finishedgoodsflag" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "color" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "color" + logicalType: "string" physicalType: "varchar[15]" description: "Product color." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/color" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "safetystocklevel" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "safetystocklevel" + logicalType: "number" physicalType: "int2" description: "Minimum inventory quantity." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/safetystocklevel" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "reorderpoint" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "reorderpoint" + logicalType: "number" physicalType: "int2" description: "Inventory level that triggers a purchase order or work order." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/reorderpoint" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "standardcost" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "standardcost" + logicalType: "number" physicalType: "numeric" description: "Standard cost of the product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/standardcost" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "listprice" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "listprice" + logicalType: "number" physicalType: "numeric" description: "Selling price." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/listprice" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "size" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "size" + logicalType: "string" physicalType: "varchar[5]" description: "Product size." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/size" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "sizeunitmeasurecode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "sizeunitmeasurecode" + logicalType: "string" physicalType: "bpchar" description: "Unit of measure for Size column." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/sizeunitmeasurecode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "weightunitmeasurecode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "weightunitmeasurecode" + logicalType: "string" physicalType: "bpchar" description: "Unit of measure for Weight column." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/weightunitmeasurecode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "weight" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "weight" + logicalType: "number" physicalType: "numeric" description: "Product weight." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/weight" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "daystomanufacture" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "daystomanufacture" + logicalType: "number" physicalType: "int4" description: "Number of days required to manufacture the product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/daystomanufacture" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "productline" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "productline" + logicalType: "string" physicalType: "bpchar" description: "R = Road, M = Mountain, T = Touring, S = Standard" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/productline" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "class" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "class" + logicalType: "string" physicalType: "bpchar" description: "H = High, M = Medium, L = Low" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/class" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "style" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "style" + logicalType: "string" physicalType: "bpchar" description: "W = Womens, M = Mens, U = Universal" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/style" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "productsubcategoryid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "productsubcategoryid" + logicalType: "number" physicalType: "int4" description: "Product is a member of this product subcategory. Foreign key to\ \ ProductSubCategory.ProductSubCategoryID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/productsubcategoryid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "productmodelid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "productmodelid" + logicalType: "number" physicalType: "int4" description: "Product is a member of this product model. Foreign key to ProductModel.ProductModelID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/productmodelid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "sellstartdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "sellstartdate" + logicalType: "date" physicalType: "timestamp" description: "Date the product was available for sale." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/sellstartdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "sellenddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "sellenddate" + logicalType: "date" physicalType: "timestamp" description: "Date the product was no longer available for sale." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/sellenddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "discontinueddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "discontinueddate" + logicalType: "date" physicalType: "timestamp" description: "Date the product was discontinued." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/discontinueddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/product/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productcategory" + criticalDataElement: false + primaryKey: false + required: false + - name: "productcategory" physicalName: "productcategory" description: "High-level product categorization." - columns: - - column: "productcategoryid" - logicalType: "Numeric" + properties: + - name: "productcategoryid" + logicalType: "number" physicalType: "serial" description: "Primary key for ProductCategory records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcategory/productcategoryid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Category description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcategory/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcategory/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcategory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productcosthistory" + criticalDataElement: false + primaryKey: false + required: false + - name: "productcosthistory" physicalName: "productcosthistory" description: "Changes in the cost of a product over time." - columns: - - column: "productid" - logicalType: "Numeric" + properties: + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcosthistory/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "startdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "startdate" + logicalType: "date" physicalType: "timestamp" description: "Product cost start date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcosthistory/startdate" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "enddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "enddate" + logicalType: "date" physicalType: "timestamp" description: "Product cost end date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcosthistory/enddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "standardcost" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "standardcost" + logicalType: "number" physicalType: "numeric" description: "Standard cost of the product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcosthistory/standardcost" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productcosthistory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productdescription" + criticalDataElement: false + primaryKey: false + required: false + - name: "productdescription" physicalName: "productdescription" description: "Product descriptions in several languages." - columns: - - column: "productdescriptionid" - logicalType: "Numeric" + properties: + - name: "productdescriptionid" + logicalType: "number" physicalType: "serial" description: "Primary key for ProductDescription records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productdescription/productdescriptionid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "description" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "description" + logicalType: "string" physicalType: "varchar[400]" description: "Description of the product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productdescription/description" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productdescription/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productdescription/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productdocument" + criticalDataElement: false + primaryKey: false + required: false + - name: "productdocument" physicalName: "productdocument" description: "Cross-reference table mapping products to related product documents." - columns: - - column: "productid" - logicalType: "Numeric" + properties: + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productdocument/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productdocument/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "documentnode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "documentnode" + logicalType: "string" physicalType: "varchar[2147483647]" description: "Document identification number. Foreign key to Document.DocumentNode." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productdocument/documentnode" - criticalDataElementStatus: false - primary: true - nullable: false - - table: "productinventory" + criticalDataElement: false + primaryKey: true + required: false + - name: "productinventory" physicalName: "productinventory" description: "Product inventory information." - columns: - - column: "productid" - logicalType: "Numeric" + properties: + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productinventory/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "locationid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "locationid" + logicalType: "number" physicalType: "int2" description: "Inventory location identification number. Foreign key to Location.LocationID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productinventory/locationid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "shelf" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "shelf" + logicalType: "string" physicalType: "varchar[10]" description: "Storage compartment within an inventory location." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productinventory/shelf" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "bin" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "bin" + logicalType: "number" physicalType: "int2" description: "Storage container on a shelf in an inventory location." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productinventory/bin" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "quantity" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "quantity" + logicalType: "number" physicalType: "int2" description: "Quantity of products in the inventory location." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productinventory/quantity" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productinventory/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productinventory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productlistpricehistory" + criticalDataElement: false + primaryKey: false + required: false + - name: "productlistpricehistory" physicalName: "productlistpricehistory" description: "Changes in the list price of a product over time." - columns: - - column: "productid" - logicalType: "Numeric" + properties: + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productlistpricehistory/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "startdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "startdate" + logicalType: "date" physicalType: "timestamp" description: "List price start date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productlistpricehistory/startdate" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "enddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "enddate" + logicalType: "date" physicalType: "timestamp" description: "List price end date" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productlistpricehistory/enddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "listprice" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "listprice" + logicalType: "number" physicalType: "numeric" description: "Product list price." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productlistpricehistory/listprice" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productlistpricehistory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productmodel" + criticalDataElement: false + primaryKey: false + required: false + - name: "productmodel" physicalName: "productmodel" description: "Product model classification." - columns: - - column: "productmodelid" - logicalType: "Numeric" + properties: + - name: "productmodelid" + logicalType: "number" physicalType: "serial" description: "Primary key for ProductModel records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodel/productmodelid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Product model description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodel/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "catalogdescription" - logicalType: "XML" + criticalDataElement: false + primaryKey: false + required: false + - name: "catalogdescription" + logicalType: "string" physicalType: "xml" description: "Detailed product catalog information in xml format." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodel/catalogdescription" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "instructions" - logicalType: "XML" + criticalDataElement: false + primaryKey: false + required: false + - name: "instructions" + logicalType: "string" physicalType: "xml" description: "Manufacturing instructions in xml format." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodel/instructions" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodel/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodel/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productmodelillustration" + criticalDataElement: false + primaryKey: false + required: false + - name: "productmodelillustration" physicalName: "productmodelillustration" description: "Cross-reference table mapping product models and illustrations." - columns: - - column: "productmodelid" - logicalType: "Numeric" + properties: + - name: "productmodelid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to ProductModel.ProductModelID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodelillustration/productmodelid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "illustrationid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "illustrationid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to Illustration.IllustrationID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodelillustration/illustrationid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodelillustration/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productmodelproductdescriptionculture" + criticalDataElement: false + primaryKey: false + required: false + - name: "productmodelproductdescriptionculture" physicalName: "productmodelproductdescriptionculture" description: "Cross-reference table mapping product descriptions and the language\ \ the description is written in." - columns: - - column: "productmodelid" - logicalType: "Numeric" + properties: + - name: "productmodelid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to ProductModel.ProductModelID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodelproductdescriptionculture/productmodelid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productdescriptionid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productdescriptionid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to ProductDescription.ProductDescriptionID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodelproductdescriptionculture/productdescriptionid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "cultureid" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "cultureid" + logicalType: "string" physicalType: "bpchar" description: "Culture identification number. Foreign key to Culture.CultureID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodelproductdescriptionculture/cultureid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productmodelproductdescriptionculture/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productphoto" + criticalDataElement: false + primaryKey: false + required: false + - name: "productphoto" physicalName: "productphoto" description: "Product images." - columns: - - column: "productphotoid" - logicalType: "Numeric" + properties: + - name: "productphotoid" + logicalType: "number" physicalType: "serial" description: "Primary key for ProductPhoto records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productphoto/productphotoid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "thumbnailphoto" - logicalType: "Binary" + criticalDataElement: false + primaryKey: true + required: false + - name: "thumbnailphoto" + logicalType: "string" physicalType: "bytea" description: "Small image of the product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productphoto/thumbnailphoto" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "thumbnailphotofilename" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "thumbnailphotofilename" + logicalType: "string" physicalType: "varchar[50]" description: "Small image file name." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productphoto/thumbnailphotofilename" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "largephoto" - logicalType: "Binary" + criticalDataElement: false + primaryKey: false + required: false + - name: "largephoto" + logicalType: "string" physicalType: "bytea" description: "Large image of the product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productphoto/largephoto" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "largephotofilename" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "largephotofilename" + logicalType: "string" physicalType: "varchar[50]" description: "Large image file name." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productphoto/largephotofilename" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productphoto/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productproductphoto" + criticalDataElement: false + primaryKey: false + required: false + - name: "productproductphoto" physicalName: "productproductphoto" description: "Cross-reference table mapping products and product photos." - columns: - - column: "productid" - logicalType: "Numeric" + properties: + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productproductphoto/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productphotoid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productphotoid" + logicalType: "number" physicalType: "int4" description: "Product photo identification number. Foreign key to ProductPhoto.ProductPhotoID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productproductphoto/productphotoid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "primary" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "primary" + logicalType: "object" physicalType: "Flag" description: "0 = Photo is not the principal image. 1 = Photo is the principal\ \ image." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productproductphoto/primary" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productproductphoto/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productreview" + criticalDataElement: false + primaryKey: false + required: false + - name: "productreview" physicalName: "productreview" description: "Customer reviews of products they have purchased." - columns: - - column: "productreviewid" - logicalType: "Numeric" + properties: + - name: "productreviewid" + logicalType: "number" physicalType: "serial" description: "Primary key for ProductReview records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productreview/productreviewid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productreview/productid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "reviewername" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "reviewername" + logicalType: "object" physicalType: "Name" description: "Name of the reviewer." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productreview/reviewername" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "reviewdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "reviewdate" + logicalType: "date" physicalType: "timestamp" description: "Date review was submitted." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productreview/reviewdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "emailaddress" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "emailaddress" + logicalType: "string" physicalType: "varchar[50]" description: "Reviewer's e-mail address." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productreview/emailaddress" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rating" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "rating" + logicalType: "number" physicalType: "int4" description: "Product rating given by the reviewer. Scale is 1 to 5 with 5 as\ \ the highest rating." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productreview/rating" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "comments" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "comments" + logicalType: "string" physicalType: "varchar[3850]" description: "Reviewer's comments" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productreview/comments" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productreview/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productsubcategory" + criticalDataElement: false + primaryKey: false + required: false + - name: "productsubcategory" physicalName: "productsubcategory" description: "Product subcategories. See ProductCategory table." - columns: - - column: "productsubcategoryid" - logicalType: "Numeric" + properties: + - name: "productsubcategoryid" + logicalType: "number" physicalType: "serial" description: "Primary key for ProductSubcategory records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productsubcategory/productsubcategoryid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productcategoryid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productcategoryid" + logicalType: "number" physicalType: "int4" description: "Product category identification number. Foreign key to ProductCategory.ProductCategoryID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productsubcategory/productcategoryid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Subcategory description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productsubcategory/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productsubcategory/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productsubcategory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "scrapreason" + criticalDataElement: false + primaryKey: false + required: false + - name: "scrapreason" physicalName: "scrapreason" description: "Manufacturing failure reasons lookup table." - columns: - - column: "scrapreasonid" - logicalType: "Numeric" + properties: + - name: "scrapreasonid" + logicalType: "number" physicalType: "serial" description: "Primary key for ScrapReason records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/scrapreason/scrapreasonid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Failure description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/scrapreason/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/scrapreason/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "transactionhistory" + criticalDataElement: false + primaryKey: false + required: false + - name: "transactionhistory" physicalName: "transactionhistory" description: "Record of each purchase order, sales order, or work order transaction\ \ year to date." - columns: - - column: "transactionid" - logicalType: "Numeric" + properties: + - name: "transactionid" + logicalType: "number" physicalType: "serial" description: "Primary key for TransactionHistory records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/transactionid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/productid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "referenceorderid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "referenceorderid" + logicalType: "number" physicalType: "int4" description: "Purchase order, sales order, or work order identification number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/referenceorderid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "referenceorderlineid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "referenceorderlineid" + logicalType: "number" physicalType: "int4" description: "Line number associated with the purchase order, sales order, or\ \ work order." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/referenceorderlineid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "transactiondate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "transactiondate" + logicalType: "date" physicalType: "timestamp" description: "Date and time of the transaction." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/transactiondate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "transactiontype" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "transactiontype" + logicalType: "string" physicalType: "bpchar" description: "W = WorkOrder, S = SalesOrder, P = PurchaseOrder" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/transactiontype" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "quantity" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "quantity" + logicalType: "number" physicalType: "int4" description: "Product quantity." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/quantity" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "actualcost" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "actualcost" + logicalType: "number" physicalType: "numeric" description: "Product cost." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/actualcost" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "transactionhistoryarchive" + criticalDataElement: false + primaryKey: false + required: false + - name: "transactionhistoryarchive" physicalName: "transactionhistoryarchive" description: "Transactions for previous years." - columns: - - column: "transactionid" - logicalType: "Numeric" + properties: + - name: "transactionid" + logicalType: "number" physicalType: "int4" description: "Primary key for TransactionHistoryArchive records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/transactionid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/productid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "referenceorderid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "referenceorderid" + logicalType: "number" physicalType: "int4" description: "Purchase order, sales order, or work order identification number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/referenceorderid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "referenceorderlineid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "referenceorderlineid" + logicalType: "number" physicalType: "int4" description: "Line number associated with the purchase order, sales order, or\ \ work order." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/referenceorderlineid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "transactiondate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "transactiondate" + logicalType: "date" physicalType: "timestamp" description: "Date and time of the transaction." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/transactiondate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "transactiontype" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "transactiontype" + logicalType: "string" physicalType: "bpchar" description: "W = Work Order, S = Sales Order, P = Purchase Order" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/transactiontype" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "quantity" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "quantity" + logicalType: "number" physicalType: "int4" description: "Product quantity." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/quantity" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "actualcost" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "actualcost" + logicalType: "number" physicalType: "numeric" description: "Product cost." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/actualcost" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/transactionhistoryarchive/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "unitmeasure" + criticalDataElement: false + primaryKey: false + required: false + - name: "unitmeasure" physicalName: "unitmeasure" description: "Unit of measure lookup table." - columns: - - column: "unitmeasurecode" - logicalType: "String" + properties: + - name: "unitmeasurecode" + logicalType: "string" physicalType: "bpchar" description: "Primary key." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/unitmeasure/unitmeasurecode" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Unit of measure description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/unitmeasure/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/unitmeasure/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "workorder" + criticalDataElement: false + primaryKey: false + required: false + - name: "workorder" physicalName: "workorder" description: "Manufacturing work orders." - columns: - - column: "workorderid" - logicalType: "Numeric" + properties: + - name: "workorderid" + logicalType: "number" physicalType: "serial" description: "Primary key for WorkOrder records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/workorderid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/productid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "orderqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "orderqty" + logicalType: "number" physicalType: "int4" description: "Product quantity to build." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/orderqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "scrappedqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "scrappedqty" + logicalType: "number" physicalType: "int2" description: "Quantity that failed inspection." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/scrappedqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "startdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "startdate" + logicalType: "date" physicalType: "timestamp" description: "Work order start date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/startdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "enddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "enddate" + logicalType: "date" physicalType: "timestamp" description: "Work order end date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/enddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "duedate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "duedate" + logicalType: "date" physicalType: "timestamp" description: "Work order due date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/duedate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "scrapreasonid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "scrapreasonid" + logicalType: "number" physicalType: "int2" description: "Reason for inspection failure." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/scrapreasonid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorder/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "workorderrouting" + criticalDataElement: false + primaryKey: false + required: false + - name: "workorderrouting" physicalName: "workorderrouting" description: "Work order details." - columns: - - column: "workorderid" - logicalType: "Numeric" + properties: + - name: "workorderid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to WorkOrder.WorkOrderID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/workorderid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "operationsequence" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "operationsequence" + logicalType: "number" physicalType: "int2" description: "Primary key. Indicates the manufacturing process sequence." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/operationsequence" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "locationid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "locationid" + logicalType: "number" physicalType: "int2" description: "Manufacturing location where the part is processed. Foreign key\ \ to Location.LocationID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/locationid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "scheduledstartdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "scheduledstartdate" + logicalType: "date" physicalType: "timestamp" description: "Planned manufacturing start date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/scheduledstartdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "scheduledenddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "scheduledenddate" + logicalType: "date" physicalType: "timestamp" description: "Planned manufacturing end date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/scheduledenddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "actualstartdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "actualstartdate" + logicalType: "date" physicalType: "timestamp" description: "Actual start date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/actualstartdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "actualenddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "actualenddate" + logicalType: "date" physicalType: "timestamp" description: "Actual end date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/actualenddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "actualresourcehrs" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "actualresourcehrs" + logicalType: "number" physicalType: "numeric" description: "Number of manufacturing hours used." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/actualresourcehrs" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "plannedcost" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "plannedcost" + logicalType: "number" physicalType: "numeric" description: "Estimated manufacturing cost." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/plannedcost" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "actualcost" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "actualcost" + logicalType: "number" physicalType: "numeric" description: "Actual manufacturing cost." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/actualcost" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/workorderrouting/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "productvendor" + criticalDataElement: false + primaryKey: false + required: false + - name: "productvendor" physicalName: "productvendor" description: "Cross-reference table mapping vendors with the products they supply." - columns: - - column: "productid" - logicalType: "Numeric" + properties: + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "businessentityid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to Vendor.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "averageleadtime" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "averageleadtime" + logicalType: "number" physicalType: "int4" description: "The average span of time (in days) between placing an order with\ \ the vendor and receiving the purchased product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/averageleadtime" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "standardprice" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "standardprice" + logicalType: "number" physicalType: "numeric" description: "The vendor's usual selling price." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/standardprice" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "lastreceiptcost" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "lastreceiptcost" + logicalType: "number" physicalType: "numeric" description: "The selling price when last purchased." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/lastreceiptcost" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "lastreceiptdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "lastreceiptdate" + logicalType: "date" physicalType: "timestamp" description: "Date the product was last received by the vendor." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/lastreceiptdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "minorderqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "minorderqty" + logicalType: "number" physicalType: "int4" description: "The maximum quantity that should be ordered." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/minorderqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "maxorderqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "maxorderqty" + logicalType: "number" physicalType: "int4" description: "The minimum quantity that should be ordered." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/maxorderqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "onorderqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "onorderqty" + logicalType: "number" physicalType: "int4" description: "The quantity currently on order." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/onorderqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "unitmeasurecode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "unitmeasurecode" + logicalType: "string" physicalType: "bpchar" description: "The product's unit of measure." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/unitmeasurecode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/productvendor/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "purchaseorderdetail" + criticalDataElement: false + primaryKey: false + required: false + - name: "purchaseorderdetail" physicalName: "purchaseorderdetail" description: "Individual products associated with a specific purchase order. See\ \ PurchaseOrderHeader." - columns: - - column: "purchaseorderid" - logicalType: "Numeric" + properties: + - name: "purchaseorderid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to PurchaseOrderHeader.PurchaseOrderID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/purchaseorderid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "purchaseorderdetailid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "purchaseorderdetailid" + logicalType: "number" physicalType: "serial" description: "Primary key. One line number per purchased product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/purchaseorderdetailid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "duedate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "duedate" + logicalType: "date" physicalType: "timestamp" description: "Date the product is expected to be received." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/duedate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "orderqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "orderqty" + logicalType: "number" physicalType: "int2" description: "Quantity ordered." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/orderqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/productid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "unitprice" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "unitprice" + logicalType: "number" physicalType: "numeric" description: "Vendor's selling price of a single product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/unitprice" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "receivedqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "receivedqty" + logicalType: "number" physicalType: "numeric" description: "Quantity actually received from the vendor." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/receivedqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rejectedqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "rejectedqty" + logicalType: "number" physicalType: "numeric" description: "Quantity rejected during inspection." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/rejectedqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderdetail/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "purchaseorderheader" + criticalDataElement: false + primaryKey: false + required: false + - name: "purchaseorderheader" physicalName: "purchaseorderheader" description: "General purchase order information. See PurchaseOrderDetail." - columns: - - column: "purchaseorderid" - logicalType: "Numeric" + properties: + - name: "purchaseorderid" + logicalType: "number" physicalType: "serial" description: "Primary key." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/purchaseorderid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "revisionnumber" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "revisionnumber" + logicalType: "number" physicalType: "int2" description: "Incremental number to track changes to the purchase order over\ \ time." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/revisionnumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "status" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "status" + logicalType: "number" physicalType: "int2" description: "Order current status. 1 = Pending; 2 = Approved; 3 = Rejected;\ \ 4 = Complete" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/status" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "employeeid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "employeeid" + logicalType: "number" physicalType: "int4" description: "Employee who created the purchase order. Foreign key to Employee.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/employeeid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "vendorid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "vendorid" + logicalType: "number" physicalType: "int4" description: "Vendor with whom the purchase order is placed. Foreign key to\ \ Vendor.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/vendorid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "shipmethodid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "shipmethodid" + logicalType: "number" physicalType: "int4" description: "Shipping method. Foreign key to ShipMethod.ShipMethodID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/shipmethodid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "orderdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "orderdate" + logicalType: "date" physicalType: "timestamp" description: "Purchase order creation date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/orderdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "shipdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "shipdate" + logicalType: "date" physicalType: "timestamp" description: "Estimated shipment date from the vendor." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/shipdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "subtotal" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "subtotal" + logicalType: "number" physicalType: "numeric" description: "Purchase order subtotal. Computed as SUM(PurchaseOrderDetail.LineTotal)for\ \ the appropriate PurchaseOrderID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/subtotal" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "taxamt" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "taxamt" + logicalType: "number" physicalType: "numeric" description: "Tax amount." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/taxamt" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "freight" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "freight" + logicalType: "number" physicalType: "numeric" description: "Shipping cost." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/freight" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/purchaseorderheader/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "shipmethod" + criticalDataElement: false + primaryKey: false + required: false + - name: "shipmethod" physicalName: "shipmethod" description: "Shipping company lookup table." - columns: - - column: "shipmethodid" - logicalType: "Numeric" + properties: + - name: "shipmethodid" + logicalType: "number" physicalType: "serial" description: "Primary key for ShipMethod records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shipmethod/shipmethodid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Shipping company name." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shipmethod/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "shipbase" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "shipbase" + logicalType: "number" physicalType: "numeric" description: "Minimum shipping charge." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shipmethod/shipbase" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "shiprate" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "shiprate" + logicalType: "number" physicalType: "numeric" description: "Shipping charge per pound." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shipmethod/shiprate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shipmethod/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shipmethod/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "vendor" + criticalDataElement: false + primaryKey: false + required: false + - name: "vendor" physicalName: "vendor" description: "Companies from whom Adventure Works Cycles purchases parts or other\ \ goods." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key for Vendor records. Foreign key to BusinessEntity.BusinessEntityID" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/vendor/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "accountnumber" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "accountnumber" + logicalType: "object" physicalType: "AccountNumber" description: "Vendor account (identification) number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/vendor/accountnumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Company name." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/vendor/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "creditrating" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "creditrating" + logicalType: "number" physicalType: "int2" description: "1 = Superior, 2 = Excellent, 3 = Above average, 4 = Average, 5\ \ = Below average" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/vendor/creditrating" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "preferredvendorstatus" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "preferredvendorstatus" + logicalType: "object" physicalType: "Flag" description: "0 = Do not use if another vendor is available. 1 = Preferred over\ \ other vendors supplying the same product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/vendor/preferredvendorstatus" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "activeflag" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "activeflag" + logicalType: "object" physicalType: "Flag" description: "0 = Vendor no longer used. 1 = Vendor is actively used." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/vendor/activeflag" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "purchasingwebserviceurl" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "purchasingwebserviceurl" + logicalType: "string" physicalType: "varchar[1024]" description: "Vendor URL." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/vendor/purchasingwebserviceurl" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/vendor/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "countryregioncurrency" + criticalDataElement: false + primaryKey: false + required: false + - name: "countryregioncurrency" physicalName: "countryregioncurrency" description: "Cross-reference table mapping ISO currency codes to a country or\ \ region." - columns: - - column: "countryregioncode" - logicalType: "String" + properties: + - name: "countryregioncode" + logicalType: "string" physicalType: "varchar[3]" description: "ISO code for countries and regions. Foreign key to CountryRegion.CountryRegionCode." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/countryregioncurrency/countryregioncode" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "currencycode" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "currencycode" + logicalType: "string" physicalType: "bpchar" description: "ISO standard currency code. Foreign key to Currency.CurrencyCode." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/countryregioncurrency/currencycode" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/countryregioncurrency/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "creditcard" + criticalDataElement: false + primaryKey: false + required: false + - name: "creditcard" physicalName: "creditcard" description: "Customer credit card information." - columns: - - column: "creditcardid" - logicalType: "Numeric" + properties: + - name: "creditcardid" + logicalType: "number" physicalType: "serial" description: "Primary key for CreditCard records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/creditcard/creditcardid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "cardtype" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "cardtype" + logicalType: "string" physicalType: "varchar[50]" description: "Credit card name." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/creditcard/cardtype" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "cardnumber" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "cardnumber" + logicalType: "string" physicalType: "varchar[25]" description: "Credit card number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/creditcard/cardnumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "expmonth" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "expmonth" + logicalType: "number" physicalType: "int2" description: "Credit card expiration month." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/creditcard/expmonth" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "expyear" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "expyear" + logicalType: "number" physicalType: "int2" description: "Credit card expiration year." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/creditcard/expyear" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/creditcard/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "currency" + criticalDataElement: false + primaryKey: false + required: false + - name: "currency" physicalName: "currency" description: "Lookup table containing standard ISO currencies." - columns: - - column: "currencycode" - logicalType: "String" + properties: + - name: "currencycode" + logicalType: "string" physicalType: "bpchar" description: "The ISO code for the Currency." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currency/currencycode" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Currency name." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currency/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currency/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "currencyrate" + criticalDataElement: false + primaryKey: false + required: false + - name: "currencyrate" physicalName: "currencyrate" description: "Currency exchange rates." - columns: - - column: "currencyrateid" - logicalType: "Numeric" + properties: + - name: "currencyrateid" + logicalType: "number" physicalType: "serial" description: "Primary key for CurrencyRate records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currencyrate/currencyrateid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "currencyratedate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "currencyratedate" + logicalType: "date" physicalType: "timestamp" description: "Date and time the exchange rate was obtained." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currencyrate/currencyratedate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "fromcurrencycode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "fromcurrencycode" + logicalType: "string" physicalType: "bpchar" description: "Exchange rate was converted from this currency code." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currencyrate/fromcurrencycode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "tocurrencycode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "tocurrencycode" + logicalType: "string" physicalType: "bpchar" description: "Exchange rate was converted to this currency code." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currencyrate/tocurrencycode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "averagerate" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "averagerate" + logicalType: "number" physicalType: "numeric" description: "Average exchange rate for the day." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currencyrate/averagerate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "endofdayrate" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "endofdayrate" + logicalType: "number" physicalType: "numeric" description: "Final exchange rate for the day." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currencyrate/endofdayrate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/currencyrate/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "customer" + criticalDataElement: false + primaryKey: false + required: false + - name: "customer" physicalName: "customer" description: "Current customer information. Also see the Person and Store tables." - columns: - - column: "customerid" - logicalType: "Numeric" + properties: + - name: "customerid" + logicalType: "number" physicalType: "serial" description: "Primary key." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/customer/customerid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "personid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "personid" + logicalType: "number" physicalType: "int4" description: "Foreign key to Person.BusinessEntityID" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/customer/personid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "storeid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "storeid" + logicalType: "number" physicalType: "int4" description: "Foreign key to Store.BusinessEntityID" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/customer/storeid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "territoryid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "territoryid" + logicalType: "number" physicalType: "int4" description: "ID of the territory in which the customer is located. Foreign\ \ key to SalesTerritory.SalesTerritoryID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/customer/territoryid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/customer/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/customer/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "personcreditcard" + criticalDataElement: false + primaryKey: false + required: false + - name: "personcreditcard" physicalName: "personcreditcard" description: "Cross-reference table mapping people to their credit card information\ \ in the CreditCard table." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Business entity identification number. Foreign key to Person.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/personcreditcard/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "creditcardid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "creditcardid" + logicalType: "number" physicalType: "int4" description: "Credit card identification number. Foreign key to CreditCard.CreditCardID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/personcreditcard/creditcardid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/personcreditcard/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salesorderdetail" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesorderdetail" physicalName: "salesorderdetail" description: "Individual products associated with a specific sales order. See\ \ SalesOrderHeader." - columns: - - column: "salesorderid" - logicalType: "Numeric" + properties: + - name: "salesorderid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to SalesOrderHeader.SalesOrderID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/salesorderid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "salesorderdetailid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "salesorderdetailid" + logicalType: "number" physicalType: "serial" description: "Primary key. One incremental unique number per product sold." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/salesorderdetailid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "carriertrackingnumber" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "carriertrackingnumber" + logicalType: "string" physicalType: "varchar[25]" description: "Shipment tracking number supplied by the shipper." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/carriertrackingnumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "orderqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "orderqty" + logicalType: "number" physicalType: "int2" description: "Quantity ordered per product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/orderqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product sold to customer. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/productid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "specialofferid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "specialofferid" + logicalType: "number" physicalType: "int4" description: "Promotional code. Foreign key to SpecialOffer.SpecialOfferID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/specialofferid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "unitprice" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "unitprice" + logicalType: "number" physicalType: "numeric" description: "Selling price of a single product." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/unitprice" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "unitpricediscount" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "unitpricediscount" + logicalType: "number" physicalType: "numeric" description: "Discount amount." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/unitpricediscount" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderdetail/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salesorderheader" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesorderheader" physicalName: "salesorderheader" description: "General sales order information." - columns: - - column: "salesorderid" - logicalType: "Numeric" + properties: + - name: "salesorderid" + logicalType: "number" physicalType: "serial" description: "Primary key." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/salesorderid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "revisionnumber" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "revisionnumber" + logicalType: "number" physicalType: "int2" description: "Incremental number to track changes to the sales order over time." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/revisionnumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "orderdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "orderdate" + logicalType: "date" physicalType: "timestamp" description: "Dates the sales order was created." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/orderdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "duedate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "duedate" + logicalType: "date" physicalType: "timestamp" description: "Date the order is due to the customer." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/duedate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "shipdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "shipdate" + logicalType: "date" physicalType: "timestamp" description: "Date the order was shipped to the customer." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/shipdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "status" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "status" + logicalType: "number" physicalType: "int2" description: "Order current status. 1 = In process; 2 = Approved; 3 = Backordered;\ \ 4 = Rejected; 5 = Shipped; 6 = Cancelled" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/status" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "onlineorderflag" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "onlineorderflag" + logicalType: "object" physicalType: "Flag" description: "0 = Order placed by sales person. 1 = Order placed online by customer." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/onlineorderflag" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "purchaseordernumber" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "purchaseordernumber" + logicalType: "object" physicalType: "OrderNumber" description: "Customer purchase order number reference." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/purchaseordernumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "accountnumber" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "accountnumber" + logicalType: "object" physicalType: "AccountNumber" description: "Financial accounting number reference." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/accountnumber" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "customerid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "customerid" + logicalType: "number" physicalType: "int4" description: "Customer identification number. Foreign key to Customer.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/customerid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "salespersonid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "salespersonid" + logicalType: "number" physicalType: "int4" description: "Sales person who created the sales order. Foreign key to SalesPerson.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/salespersonid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "territoryid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "territoryid" + logicalType: "number" physicalType: "int4" description: "Territory in which the sale was made. Foreign key to SalesTerritory.SalesTerritoryID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/territoryid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "billtoaddressid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "billtoaddressid" + logicalType: "number" physicalType: "int4" description: "Customer billing address. Foreign key to Address.AddressID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/billtoaddressid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "shiptoaddressid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "shiptoaddressid" + logicalType: "number" physicalType: "int4" description: "Customer shipping address. Foreign key to Address.AddressID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/shiptoaddressid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "shipmethodid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "shipmethodid" + logicalType: "number" physicalType: "int4" description: "Shipping method. Foreign key to ShipMethod.ShipMethodID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/shipmethodid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "creditcardid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "creditcardid" + logicalType: "number" physicalType: "int4" description: "Credit card identification number. Foreign key to CreditCard.CreditCardID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/creditcardid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "creditcardapprovalcode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "creditcardapprovalcode" + logicalType: "string" physicalType: "varchar[15]" description: "Approval code provided by the credit card company." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/creditcardapprovalcode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "currencyrateid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "currencyrateid" + logicalType: "number" physicalType: "int4" description: "Currency exchange rate used. Foreign key to CurrencyRate.CurrencyRateID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/currencyrateid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "subtotal" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "subtotal" + logicalType: "number" physicalType: "numeric" description: "Sales subtotal. Computed as SUM(SalesOrderDetail.LineTotal)for\ \ the appropriate SalesOrderID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/subtotal" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "taxamt" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "taxamt" + logicalType: "number" physicalType: "numeric" description: "Tax amount." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/taxamt" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "freight" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "freight" + logicalType: "number" physicalType: "numeric" description: "Shipping cost." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/freight" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "totaldue" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "totaldue" + logicalType: "number" physicalType: "numeric" description: "Total due from customer. Computed as Subtotal + TaxAmt + Freight." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/totaldue" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "comment" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "comment" + logicalType: "string" physicalType: "varchar[128]" description: "Sales representative comments." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/comment" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheader/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salesorderheadersalesreason" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesorderheadersalesreason" physicalName: "salesorderheadersalesreason" description: "Cross-reference table mapping sales orders to sales reason codes." - columns: - - column: "salesorderid" - logicalType: "Numeric" + properties: + - name: "salesorderid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to SalesOrderHeader.SalesOrderID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheadersalesreason/salesorderid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "salesreasonid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "salesreasonid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to SalesReason.SalesReasonID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheadersalesreason/salesreasonid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesorderheadersalesreason/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salesperson" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesperson" physicalName: "salesperson" description: "Sales representative current information." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key for SalesPerson records. Foreign key to Employee.BusinessEntityID" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "territoryid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "territoryid" + logicalType: "number" physicalType: "int4" description: "Territory currently assigned to. Foreign key to SalesTerritory.SalesTerritoryID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/territoryid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "salesquota" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesquota" + logicalType: "number" physicalType: "numeric" description: "Projected yearly sales." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/salesquota" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "bonus" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "bonus" + logicalType: "number" physicalType: "numeric" description: "Bonus due if quota is met." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/bonus" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "commissionpct" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "commissionpct" + logicalType: "number" physicalType: "numeric" description: "Commision percent received per sale." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/commissionpct" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "salesytd" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesytd" + logicalType: "number" physicalType: "numeric" description: "Sales total year to date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/salesytd" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "saleslastyear" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "saleslastyear" + logicalType: "number" physicalType: "numeric" description: "Sales total of previous year." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/saleslastyear" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesperson/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salespersonquotahistory" + criticalDataElement: false + primaryKey: false + required: false + - name: "salespersonquotahistory" physicalName: "salespersonquotahistory" description: "Sales performance tracking." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Sales person identification number. Foreign key to SalesPerson.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salespersonquotahistory/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "quotadate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "quotadate" + logicalType: "date" physicalType: "timestamp" description: "Sales quota date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salespersonquotahistory/quotadate" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "salesquota" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "salesquota" + logicalType: "number" physicalType: "numeric" description: "Sales quota amount." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salespersonquotahistory/salesquota" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salespersonquotahistory/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salespersonquotahistory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salesreason" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesreason" physicalName: "salesreason" description: "Lookup table of customer purchase reasons." - columns: - - column: "salesreasonid" - logicalType: "Numeric" + properties: + - name: "salesreasonid" + logicalType: "number" physicalType: "serial" description: "Primary key for SalesReason records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesreason/salesreasonid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Sales reason description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesreason/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "reasontype" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "reasontype" + logicalType: "object" physicalType: "Name" description: "Category the sales reason belongs to." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesreason/reasontype" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesreason/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salestaxrate" + criticalDataElement: false + primaryKey: false + required: false + - name: "salestaxrate" physicalName: "salestaxrate" description: "Tax rate lookup table." - columns: - - column: "salestaxrateid" - logicalType: "Numeric" + properties: + - name: "salestaxrateid" + logicalType: "number" physicalType: "serial" description: "Primary key for SalesTaxRate records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salestaxrate/salestaxrateid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "stateprovinceid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "stateprovinceid" + logicalType: "number" physicalType: "int4" description: "State, province, or country/region the sales tax applies to." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salestaxrate/stateprovinceid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "taxtype" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "taxtype" + logicalType: "number" physicalType: "int2" description: "1 = Tax applied to retail transactions, 2 = Tax applied to wholesale\ \ transactions, 3 = Tax applied to all sales (retail and wholesale) transactions." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salestaxrate/taxtype" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "taxrate" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "taxrate" + logicalType: "number" physicalType: "numeric" description: "Tax rate amount." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salestaxrate/taxrate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: false + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Tax rate description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salestaxrate/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salestaxrate/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salestaxrate/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salesterritory" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesterritory" physicalName: "salesterritory" description: "Sales territory lookup table." - columns: - - column: "territoryid" - logicalType: "Numeric" + properties: + - name: "territoryid" + logicalType: "number" physicalType: "serial" description: "Primary key for SalesTerritory records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/territoryid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Sales territory description" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "countryregioncode" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "countryregioncode" + logicalType: "string" physicalType: "varchar[3]" description: "ISO standard country or region code. Foreign key to CountryRegion.CountryRegionCode." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/countryregioncode" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "group" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "group" + logicalType: "string" physicalType: "varchar[50]" description: "Geographic area to which the sales territory belong." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/group" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "salesytd" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesytd" + logicalType: "number" physicalType: "numeric" description: "Sales in the territory year to date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/salesytd" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "saleslastyear" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "saleslastyear" + logicalType: "number" physicalType: "numeric" description: "Sales in the territory the previous year." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/saleslastyear" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "costytd" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "costytd" + logicalType: "number" physicalType: "numeric" description: "Business costs in the territory year to date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/costytd" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "costlastyear" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "costlastyear" + logicalType: "number" physicalType: "numeric" description: "Business costs in the territory the previous year." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/costlastyear" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "salesterritoryhistory" + criticalDataElement: false + primaryKey: false + required: false + - name: "salesterritoryhistory" physicalName: "salesterritoryhistory" description: "Sales representative transfers to other sales territories." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key. The sales rep. Foreign key to SalesPerson.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritoryhistory/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "territoryid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "territoryid" + logicalType: "number" physicalType: "int4" description: "Primary key. Territory identification number. Foreign key to SalesTerritory.SalesTerritoryID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritoryhistory/territoryid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "startdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "startdate" + logicalType: "date" physicalType: "timestamp" description: "Primary key. Date the sales representive started work in the territory." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritoryhistory/startdate" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "enddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: true + required: false + - name: "enddate" + logicalType: "date" physicalType: "timestamp" description: "Date the sales representative left work in the territory." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritoryhistory/enddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritoryhistory/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/salesterritoryhistory/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "shoppingcartitem" + criticalDataElement: false + primaryKey: false + required: false + - name: "shoppingcartitem" physicalName: "shoppingcartitem" description: "Contains online customer orders until the order is submitted or\ \ cancelled." - columns: - - column: "shoppingcartitemid" - logicalType: "Numeric" + properties: + - name: "shoppingcartitemid" + logicalType: "number" physicalType: "serial" description: "Primary key for ShoppingCartItem records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shoppingcartitem/shoppingcartitemid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "shoppingcartid" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "shoppingcartid" + logicalType: "string" physicalType: "varchar[50]" description: "Shopping cart identification number." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shoppingcartitem/shoppingcartid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "quantity" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "quantity" + logicalType: "number" physicalType: "int4" description: "Product quantity ordered." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shoppingcartitem/quantity" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product ordered. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shoppingcartitem/productid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "datecreated" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "datecreated" + logicalType: "date" physicalType: "timestamp" description: "Date the time the record was created." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shoppingcartitem/datecreated" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/shoppingcartitem/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "specialoffer" + criticalDataElement: false + primaryKey: false + required: false + - name: "specialoffer" physicalName: "specialoffer" description: "Sale discounts lookup table." - columns: - - column: "specialofferid" - logicalType: "Numeric" + properties: + - name: "specialofferid" + logicalType: "number" physicalType: "serial" description: "Primary key for SpecialOffer records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/specialofferid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "description" - logicalType: "String" + criticalDataElement: false + primaryKey: true + required: false + - name: "description" + logicalType: "string" physicalType: "varchar[255]" description: "Discount description." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/description" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "discountpct" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "discountpct" + logicalType: "number" physicalType: "numeric" description: "Discount precentage." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/discountpct" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "type" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "type" + logicalType: "string" physicalType: "varchar[50]" description: "Discount type category." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/type" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "category" - logicalType: "String" + criticalDataElement: false + primaryKey: false + required: false + - name: "category" + logicalType: "string" physicalType: "varchar[50]" description: "Group the discount applies to such as Reseller or Customer." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/category" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "startdate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "startdate" + logicalType: "date" physicalType: "timestamp" description: "Discount start date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/startdate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "enddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "enddate" + logicalType: "date" physicalType: "timestamp" description: "Discount end date." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/enddate" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "minqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "minqty" + logicalType: "number" physicalType: "int4" description: "Minimum discount percent allowed." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/minqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "maxqty" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "maxqty" + logicalType: "number" physicalType: "int4" description: "Maximum discount percent allowed." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/maxqty" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialoffer/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "specialofferproduct" + criticalDataElement: false + primaryKey: false + required: false + - name: "specialofferproduct" physicalName: "specialofferproduct" description: "Cross-reference table mapping products to special offer discounts." - columns: - - column: "specialofferid" - logicalType: "Numeric" + properties: + - name: "specialofferid" + logicalType: "number" physicalType: "int4" description: "Primary key for SpecialOfferProduct records." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialofferproduct/specialofferid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "productid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: true + required: false + - name: "productid" + logicalType: "number" physicalType: "int4" description: "Product identification number. Foreign key to Product.ProductID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialofferproduct/productid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: true + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialofferproduct/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/specialofferproduct/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false - - table: "store" + criticalDataElement: false + primaryKey: false + required: false + - name: "store" physicalName: "store" description: "Customers (resellers) of Adventure Works products." - columns: - - column: "businessentityid" - logicalType: "Numeric" + properties: + - name: "businessentityid" + logicalType: "number" physicalType: "int4" description: "Primary key. Foreign key to Customer.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/store/businessentityid" - criticalDataElementStatus: false - primary: true - nullable: false - - column: "name" - logicalType: "Object" + criticalDataElement: false + primaryKey: true + required: false + - name: "name" + logicalType: "object" physicalType: "Name" description: "Name of the store." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/store/name" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "salespersonid" - logicalType: "Numeric" + criticalDataElement: false + primaryKey: false + required: false + - name: "salespersonid" + logicalType: "number" physicalType: "int4" description: "ID of the sales person assigned to the customer. Foreign key to\ \ SalesPerson.BusinessEntityID." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/store/salespersonid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "demographics" - logicalType: "XML" + criticalDataElement: false + primaryKey: false + required: false + - name: "demographics" + logicalType: "string" physicalType: "xml" description: "Demographic informationg about the store such as the number of\ \ employees, annual sales and store type." - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/store/demographics" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "rowguid" - logicalType: "UUID" + criticalDataElement: false + primaryKey: false + required: false + - name: "rowguid" + logicalType: "string" physicalType: "uuid" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/store/rowguid" - criticalDataElementStatus: false - primary: false - nullable: false - - column: "modifieddate" - logicalType: "Timestamp" + criticalDataElement: false + primaryKey: false + required: false + - name: "modifieddate" + logicalType: "date" physicalType: "timestamp" - partitionStatus: false - clusterStatus: false + partitioned: false authoritativeDefinitions: - type: "implementation" url: "jdbc:postgresql://localhost:5432/adventureworks/store/modifieddate" - criticalDataElementStatus: false - primary: false - nullable: false -contractCreatedTs: "2023-09-28 20:24:49.331 UTC" + criticalDataElement: false + primaryKey: false + required: false +contractCreatedTs: "2023-09-28T20:24:49.331+00:00" diff --git a/docs/examples/data-types/all-data-types.odcs.yaml b/docs/examples/data-types/all-data-types.odcs.yaml index 66dc53c..a73f417 100644 --- a/docs/examples/data-types/all-data-types.odcs.yaml +++ b/docs/examples/data-types/all-data-types.odcs.yaml @@ -1,43 +1,44 @@ version: 1.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: - - table: transactions_tbl +name: my_table +dataProduct: my_quantum +apiVersion: v3.0.0 +schema: + - name: transactions_tbl description: Provides core payment metrics - dataGranularity: Aggregation on columns txn_ref_dt, pmt_txn_id - columns: - - column: account_id + dataGranularityDescription: Aggregation on names txn_ref_dt, pmt_txn_id + properties: + - name: account_id physicalType: string logicalType: string logicalTypeOptions: minLength: 11 maxLength: 11 pattern: ACC[0-9]{8} - - column: txn_ref_date + - name: txn_ref_date physicalType: date logicalType: date logicalTypeOptions: - minimum: 2020-01-01 - maximum: 2021-01-01 + minimum: "2020-01-01" + maximum: "2021-01-01" format: yyyy-MM-dd - - column: txn_timestamp + - name: txn_timestamp physicalType: timestamp logicalType: date logicalTypeOptions: - minimum: 2020-01-01 00:00:00 - maximum: 2021-01-01 00:00:00 + minimum: "2020-01-01 00:00:00" + maximum: "2021-01-01 00:00:00" format: "yyyy-MM-dd HH:mm:ss" - - column: amount + - name: amount physicalType: double logicalType: number logicalTypeOptions: minimum: 0 format: f32 - - column: age + - name: age physicalType: int logicalType: integer logicalTypeOptions: @@ -45,17 +46,17 @@ dataset: maximum: 100 exclusiveMaximum: true format: i64 - - column: is_open + - name: is_open physicalType: bool logicalType: boolean - - column: latest_txns + - name: latest_txns physicalType: list logicalType: array logicalTypeOptions: minItems: 0 maxItems: 3 uniqueItems: true - - column: customer_details + - name: customer_details physicalType: json logicalType: object logicalTypeOptions: diff --git a/docs/examples/fundamentals/table-column-description.odcs.yaml b/docs/examples/fundamentals/table-column-description.odcs.yaml index 99ed466..d0c1563 100644 --- a/docs/examples/fundamentals/table-column-description.odcs.yaml +++ b/docs/examples/fundamentals/table-column-description.odcs.yaml @@ -1,20 +1,20 @@ version: 1.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: - - table: tbl +name: my_quantum +apiVersion: v3.0.0 +schema: + - name: tbl description: Provides core payment metrics - dataGranularity: Aggregation on columns txn_ref_dt, pmt_txn_id - columns: - - column: txn_ref_dt + dataGranularityDescription: Aggregation on columns txn_ref_dt, pmt_txn_id + properties: + - name: txn_ref_dt businessName: Transaction reference date logicalType: date physicalType: date description: Reference date for the transaction. Use this date in reports and aggregation rather than txn_mystical_dt, as it is slightly too mystical. - sampleValues: + examples: - 2022-10-03 - 2025-01-28 diff --git a/docs/examples/quality/column-accuracy.odcs.yaml b/docs/examples/quality/column-accuracy.odcs.yaml index d9ec23a..b29e182 100644 --- a/docs/examples/quality/column-accuracy.odcs.yaml +++ b/docs/examples/quality/column-accuracy.odcs.yaml @@ -1,26 +1,27 @@ version: 1.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: - - table: Air_Quality +name: my_table +dataProduct: my_quantum +apiVersion: v3.0.0 +schema: + - name: Air_Quality description: Air quality of the city of New York authoritativeDefinitions: - url: https://catalog.data.gov/dataset/air-quality type: Reference definition on Data.gov - dataGranularity: Raw records - columns: - - column: DataValue + dataGranularityDescription: Raw records + properties: + - name: DataValue businessName: Measured value logicalType: number physicalType: float(3,2) quality: - templateName: RangeCheck toolName: ClimateQuantumDataQualityPackage - description: 'This column should contain positive values under 500' + description: 'This name should contain positive values under 500' dimension: accuracy severity: error businessImpact: operational diff --git a/docs/examples/quality/column-completeness.odcs.yaml b/docs/examples/quality/column-completeness.odcs.yaml index 6397fd7..15f7376 100644 --- a/docs/examples/quality/column-completeness.odcs.yaml +++ b/docs/examples/quality/column-completeness.odcs.yaml @@ -1,20 +1,21 @@ version: 1.0.0 +apiVersion: v3.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: - - table: Air_Quality +name: my_table +dataProduct: my_quantum +schema: + - name: Air_Quality description: Air quality of the city of New York authoritativeDefinitions: - url: https://catalog.data.gov/dataset/air-quality type: Reference definition on Data.gov - dataGranularity: Raw records - columns: - - column: UniqueID - isPrimaryKey: true + dataGranularityDescription: Raw records + properties: + - name: UniqueID + primaryKey: true businessName: Unique identifier logicalType: number physicalType: int diff --git a/docs/examples/quality/column-validity.odcs.yaml b/docs/examples/quality/column-validity.odcs.yaml index 29c8f7a..3c686fd 100644 --- a/docs/examples/quality/column-validity.odcs.yaml +++ b/docs/examples/quality/column-validity.odcs.yaml @@ -1,20 +1,21 @@ version: 1.0.0 +apiVersion: v3.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: - - table: Air_Quality +name: my_table +dataProduct: my_quantum +schema: + - name: Air_Quality description: Air quality of the city of New York authoritativeDefinitions: - url: https://catalog.data.gov/dataset/air-quality type: Reference definition on Data.gov - dataGranularity: Raw records - columns: - - column: UniqueID - isPrimaryKey: true + dataGranularityDescription: Raw records + properties: + - name: UniqueID + primaryKey: true businessName: Unique identifier logicalType: number physicalType: int diff --git a/docs/examples/roles/service-and-operational-roles.odcs.yaml b/docs/examples/roles/service-and-operational-roles.odcs.yaml index dd34e88..2766937 100644 --- a/docs/examples/roles/service-and-operational-roles.odcs.yaml +++ b/docs/examples/roles/service-and-operational-roles.odcs.yaml @@ -1,11 +1,12 @@ version: 1.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: [] +name: my_table +dataProduct: my_quantum +schema: [] +apiVersion: v3.0.0 roles: - role: microstrategy_user_opr access: read diff --git a/docs/examples/schema/all-schema-types.odcs.yaml b/docs/examples/schema/all-schema-types.odcs.yaml new file mode 100644 index 0000000..238dd88 --- /dev/null +++ b/docs/examples/schema/all-schema-types.odcs.yaml @@ -0,0 +1,103 @@ +version: 1.0.0 +kind: DataContract +id: 53581432-6c55-4ba2-a65f-72344a91553a +type: tables +status: current +name: my_quantum +apiVersion: v3.0.0 +schema: + - name: tbl + logicalType: object + physicalType: table + physicalName: tbl_1 + description: Provides core payment metrics + authoritativeDefinitions: + - url: https://catalog.data.gov/dataset/air-quality + type: businessDefinition + - url: https://youtu.be/jbY1BKFj9ec + type: videoTutorial + tags: [] + dataGranularityDescription: Aggregation on columns txn_ref_dt, pmt_txn_id + properties: + - name: txn_ref_dt + primaryKey: false + primaryKeyPosition: -1 + businessName: transaction reference date + logicalType: date + physicalType: date + required: false + description: transaction ref date + partitioned: true + partitionKeyPosition: 1 + criticalDataElement: false + tags: [] + classification: public + transformSourceObjects: + - table_name_1 + - table_name_2 + - table_name_3 + transformLogic: sel t1.txn_dt as txn_ref_dt from table_name_1 as t1, table_name_2 as t2, table_name_3 as t3 where t1.txn_dt=date-3 + transformDescription: Defines the logic in business terms. + examples: + - "2022-10-03" + - "2020-01-28" + - name: rcvr_id + primaryKey: true + primaryKeyPosition: 1 + businessName: receiver id + logicalType: string + physicalType: varchar(18) + required: false + description: A description for column rcvr_id. + partitioned: false + partitionKeyPosition: -1 + criticalDataElement: false + tags: [] + classification: restricted + encryptedName: enc_rcvr_id + - name: rcvr_cntry_code + primaryKey: false + primaryKeyPosition: -1 + businessName: receiver country code + logicalType: string + physicalType: varchar(2) + required: false + description: country code + partitioned: false + partitionKeyPosition: -1 + criticalDataElement: false + tags: [] + classification: public + authoritativeDefinitions: + - url: https://collibra.com/asset/742b358f-71a5-4ab1-bda4-dcdba9418c25 + type: businessDefinition + - url: https://github.com/myorg/myrepo + type: transformationImplementation + - url: jdbc:postgresql://localhost:5432/adventureworks/tbl_1/rcvr_cntry_code + type: implementation + encryptedName: rcvr_cntry_code_encrypted + - name: AnObject + logicalType: object + properties: + - name: street_lines + logicalType: array + physicalType: array + items: + physicalType: string + logicalType: string + - name: AnotherObject + logicalType: object + properties: + - name: x + logicalType: array + physicalType: array + items: + logicalType: object + physicalType: object + properties: + - name: id + logicalType: string + physicalType: VARCHAR(40) + - name: zip + logicalType: string + physicalType: VARCHAR(15) \ No newline at end of file diff --git a/docs/examples/schema/table-column.odcs.yaml b/docs/examples/schema/table-column.odcs.yaml index 7ca324b..9079758 100644 --- a/docs/examples/schema/table-column.odcs.yaml +++ b/docs/examples/schema/table-column.odcs.yaml @@ -1,14 +1,15 @@ version: 1.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553b type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: - - table: tbl - columns: - - column: rcvr_cntry_code +name: my_table +dataProduct: my_quantum +apiVersion: v3.0.0 +schema: + - name: tbl + properties: + - name: rcvr_cntry_code businessName: Receiver country code logicalType: string physicalType: varchar(2) diff --git a/docs/examples/schema/table-columns-with-partition.odcs.yaml b/docs/examples/schema/table-columns-with-partition.odcs.yaml index 5e487ac..bd2d2f2 100644 --- a/docs/examples/schema/table-columns-with-partition.odcs.yaml +++ b/docs/examples/schema/table-columns-with-partition.odcs.yaml @@ -1,43 +1,39 @@ version: 1.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553c type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: - - table: tbl - columns: - - column: rcvr_cntry_code - businessName: Receiver country code - logicalType: string - physicalType: varchar(2) - isPrimaryKey: true - primaryKeyPosition: 1 - partitionStatus: true - partitionKeyPosition: 1 - clusterStatus: false - - column: rcvr_id - businessName: Receiver identification number - logicalType: string - physicalType: varchar(20) - isPrimaryKey: true - primaryKeyPosition: 2 - partitionStatus: false - clusterStatus: false - - column: year - businessName: Year of transaction - logicalType: integer - physicalType: int - isPrimaryKey: false - partitionStatus: true - partitionKeyPosition: 2 - clusterStatus: true - clusterKeyPosition: 1 - - column: amount - businessName: Transaction amount - logicalType: double - physicalType: double - isPrimaryKey: false - partitionStatus: false - clusterStatus: false +name: my_table +dataProduct: my_quantum +apiVersion: v3.0.0 +schema: + - name: tbl + properties: + - name: rcvr_cntry_code + businessName: Receiver country code + logicalType: string + physicalType: varchar(2) + primaryKey: true + primaryKeyPosition: 1 + partitioned: true + partitionKeyPosition: 1 + - name: rcvr_id + businessName: Receiver identification number + logicalType: string + physicalType: varchar(20) + primaryKey: true + primaryKeyPosition: 2 + partitioned: false + - name: year + businessName: Year of transaction + logicalType: integer + physicalType: int + primaryKey: false + partitioned: true + partitionKeyPosition: 2 + - name: amount + businessName: Transaction amount + logicalType: number + physicalType: double + primaryKey: false + partitioned: false diff --git a/docs/examples/server/azure-server.odcs.yaml b/docs/examples/server/azure-server.odcs.yaml new file mode 100644 index 0000000..9d3c23d --- /dev/null +++ b/docs/examples/server/azure-server.odcs.yaml @@ -0,0 +1,10 @@ +version: 1.0.0 +apiVersion: v3.0.0 +kind: DataContract +id: abc123 +status: pending +servers: + - server: my-azure + type: azure + location: az://my-data-location + format: parquet diff --git a/docs/examples/sla/database-table-sla.odcs.yaml b/docs/examples/sla/database-table-sla.odcs.yaml index 643c290..2044afe 100644 --- a/docs/examples/sla/database-table-sla.odcs.yaml +++ b/docs/examples/sla/database-table-sla.odcs.yaml @@ -1,24 +1,25 @@ version: 1.0.0 +apiVersion: v3.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: [] +name: my_table +dataProduct: my_quantum +schema: [] # SLA -slaDefaultColumn: tab1.txn_ref_dt # Optional, default value is partitionColumn. +slaDefaultElement: tab1.txn_ref_dt # Optional, default value is partitionColumn. slaProperties: - property: latency # Property, see list of values in DP QoS value: 4 unit: d # d, day, days for days; y, yr, years for years column: tab1.txn_ref_dt # This would not be needed as it is the same table.column as the default one - property: generalAvailability - value: 2022-05-12T09:30:10-08:00 + value: "2022-05-12T09:30:10-08:00" - property: endOfSupport - value: 2032-05-12T09:30:10-08:00 + value: "2032-05-12T09:30:10-08:00" - property: endOfLife - value: 2042-05-12T09:30:10-08:00 + value: "2042-05-12T09:30:10-08:00" - property: retention value: 3 unit: y diff --git a/docs/examples/stakeholders/basic-four-dpo.odcs.yaml b/docs/examples/stakeholders/basic-four-dpo.odcs.yaml index 6eec799..aa38499 100644 --- a/docs/examples/stakeholders/basic-four-dpo.odcs.yaml +++ b/docs/examples/stakeholders/basic-four-dpo.odcs.yaml @@ -1,28 +1,29 @@ version: 1.0.0 +apiVersion: v3.0.0 kind: DataContract -uuid: 53581432-6c55-4ba2-a65f-72344a91553a +id: 53581432-6c55-4ba2-a65f-72344a91553a type: tables status: current -datasetName: my_table -quantumName: my_quantum -dataset: [] -stakeholders: +name: my_table +dataProduct: my_quantum +schema: [ ] +team: - username: ceastwood role: dpo - dateIn: 2014-08-02 - dateOut: 2014-10-01 + dateIn: "2014-08-02" + dateOut: "2014-10-01" replacedByUsername: jwayne - username: jwayne role: dpo - dateIn: 2014-10-01 - dateOut: 2019-03-14 + dateIn: "2014-10-01" + dateOut: "2019-03-14" replacedByUsername: cjane - username: cjane role: dpo - dateIn: 2019-03-14 + dateIn: "2019-03-14" comment: Minor interruption due to sabbatical, will be back by end of April 2021 - dateOut: 2021-04-01 + dateOut: "2021-04-01" replacedByUsername: bkid - username: bkid role: dpo - dateIn: 2021-04-01 + dateIn: "2021-04-01" diff --git a/docs/standard.md b/docs/standard.md index a00b212..98c2ef9 100644 --- a/docs/standard.md +++ b/docs/standard.md @@ -75,7 +75,7 @@ tags: null | domain | Domain | No | Name of the logical data domain. | | dataProduct | Data Product | No | The name of the data product. | | description | Description | No | Object. | -| description.purpose | Purpose | No | What is the intendet purpose for the provided data. | +| description.purpose | Purpose | No | What is the intended purpose for the provided data. | | description.limitations | Limitations | No | Technical, compliance, and legal limitations for using the data. | | description.usage | Usage | No | How to use the data. | @@ -178,11 +178,11 @@ schema: ```yaml schema: - name: AnObject - logicalType: object + logicalType: object properties: - name: street_lines logicalType: array - items: + items: logicalType: string ``` @@ -191,18 +191,18 @@ schema: ```yaml schema: - name: AnotherObject - logicalType: object + logicalType: object properties: - name: x - logicalType: array + logicalType: array items: logicalType: object properties: - name: id - logicalType: uuid + logicalType: string physicalType: VARCHAR(40) - name: zip - logicalType: string + logicalType: string physicalType: VARCHAR(15) ``` @@ -218,47 +218,46 @@ Note: the description needs to be updated. #### Applicable to Elements (either Objects or Properties) -| Key | UX label | Required | Description | -|--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| physicalName | Physical Name | No | Physical name. | -| description | Description | No | Description of the element. | -| businessName | Business Name | No | The business name of the element. | -| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. See `authoritativeDefinitions` below. | -| tags | Tags | No | A list of tags that may be assigned to the elements (object or property); the tags keyword may appear at any level. | +| Key | UX label | Required | Description | +|--------------------------|------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| name | Name | Yes | Name of the element. | +| physicalName | Physical Name | No | Physical name. | +| description | Description | No | Description of the element. | +| businessName | Business Name | No | The business name of the element. | +| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. See `authoritativeDefinitions` below. | +| tags | Tags | No | A list of tags that may be assigned to the elements (object or property); the tags keyword may appear at any level. | #### Applicable to Objects -| Key | UX label | Required | Description | -|--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| dataGranularityDescription | Data Granularity | No | Granular level of the data in the table. Example would be "Aggregation by country." | +| Key | UX label | Required | Description | +|--------------------------------------------------------|------------------------------|----------|--------------------------------------------------------------------------------------| +| dataGranularityDescription | Data Granularity | No | Granular level of the data in the object. Example would be "Aggregation by country." | #### Applicable to Properties Some keys are more applicable when the described property is a column. -| Key | UX label | Required | Description | -|--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| primaryKey | Primary Key | No | Boolean value specifying whether the field is primary or not. Default is false. | -| primaryKeyPosition | Primary Key Position | No | If field is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1. | -| logicalType | Logical Type | Yes | The logical field datatype. One of `string`, `date`, `number`, `integer`, `object`, `array` or `boolean`. | -| logicalTypeOptions | Logical Type Options | No | Additional optional metadata to describe the logical type. See [here](#logical-type-options) for more details about supported options for each `logicalType`. | -| physicalType | Physical Type | Yes | The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT. | -| description | Description | No | Description of the column. | -| required | Required | No | Indicates if the column may contain Null values; possible values are true and false. Default is false. | -| unique | Unique | No | Indicates if the column contains unique values; possible values are true and false. Default is false. | -| partitionStatus | Partition Status | No | Indicates if the column is partitioned; possible values are true and false. | -| partitionKeyPosition | Partition Key Position | No | If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1. | -| clusterStatus | Cluster Status | No | Indicates of the column is clustered; possible values are true and false. | -| clusterKeyPosition | Cluster Key Position | No | If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1. | -| classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5. | -| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on column logic or values; examples would be URL to a GitHub repo, Collibra, on another tool. | -| encryptedColumnName | Encrypted Column Name | No | The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`. | -| transformSourceObjects | Transform Sources | No | List of objects in the data source used in the transformation. | -| transformLogic | Transform Logic | No | Logic used in the column transformation. | -| transformDescription | Transform Description | No | Describes the transform logic in very simple terms. | -| examples | Example Values | No | List of sample column values. | -| criticalDataElement | Critical Data Element Status | No | True or false indicator; If element is considered a critical data element (CDE) then true else false. | -| items | Items | No | List of items in an array (only applicable when `logicalType: array`) | +| Key | UX label | Required | Description | +|--------------------------|------------------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| primaryKey | Primary Key | No | Boolean value specifying whether the field is primary or not. Default is false. | +| primaryKeyPosition | Primary Key Position | No | If field is a primary key, the position of the primary key element. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1. | +| logicalType | Logical Type | Yes | The logical field datatype. One of `string`, `date`, `number`, `integer`, `object`, `array` or `boolean`. | +| logicalTypeOptions | Logical Type Options | No | Additional optional metadata to describe the logical type. See [here](#logical-type-options) for more details about supported options for each `logicalType`. | +| physicalType | Physical Type | Yes | The physical element data type in the data source. For example, VARCHAR(2), DOUBLE, INT. | +| description | Description | No | Description of the element. | +| required | Required | No | Indicates if the element may contain Null values; possible values are true and false. Default is false. | +| unique | Unique | No | Indicates if the element contains unique values; possible values are true and false. Default is false. | +| partitioned | Partitioned | No | Indicates if the element is partitioned; possible values are true and false. | +| partitionKeyPosition | Partition Key Position | No | If element is used for partitioning, the position of the partition element. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1. | +| classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5. | +| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on element logic or values; examples would be URL to a GitHub repo, Collibra, on another tool. | +| encryptedName | Encrypted Name | No | The element name within the dataset that contains the encrypted element value. For example, unencrypted element `email_address` might have an encryptedName of `email_address_encrypt`. | +| transformSourceObjects | Transform Sources | No | List of objects in the data source used in the transformation. | +| transformLogic | Transform Logic | No | Logic used in the column transformation. | +| transformDescription | Transform Description | No | Describes the transform logic in very simple terms. | +| examples | Example Values | No | List of sample element values. | +| criticalDataElement | Critical Data Element Status | No | True or false indicator; If element is considered a critical data element (CDE) then true else false. | +| items | Items | No | List of items in an array (only applicable when `logicalType: array`) | ### Logical Type Options @@ -448,15 +447,15 @@ support: ### Definitions -| Key | UX label | Required | Description | -|------------------------|--------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------| -| support | Support | No | Top level for support channels | -| support.channel | Channel | Yes | Channel name or identifier. | -| support.url | Channel URL | Yes | Access URL using normal [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax) (https, mailto, etc.). | -| support.description | Descripton | No | Description of the channel, free text. | -| support.tool | Tool | No | Name of the tool, value can be `email`, `slack`, `teams`, `discord`, `ticket`, or `other`. | -| support.scope | Scope | No | Scope can be: `interactive`, `announcements`, `issues`. | -| support.invitationUrl | Invitation URL | No | Some tools uses invitation URL for requesting or subscribing. Follows the [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax). | +| Key | UX label | Required | Description | +|-----------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------------------------| +| support | Support | No | Top level for support channels. | +| support.channel | Channel | Yes | Channel name or identifier. | +| support.url | Channel URL | Yes | Access URL using normal [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax) (https, mailto, etc.). | +| support.description | Description | No | Description of the channel, free text. | +| support.tool | Tool | No | Name of the tool, value can be `email`, `slack`, `teams`, `discord`, `ticket`, or `other`. | +| support.scope | Scope | No | Scope can be: `interactive`, `announcements`, `issues`. | +| support.invitationUrl | Invitation URL | No | Some tools uses invitation URL for requesting or subscribing. Follows the [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax). | ## Pricing @@ -541,14 +540,14 @@ roles: ### Definitions -| Key | UX label | Required | Description | -|----------------------------|---------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------| -| roles | Roles | No | Array. A list of roles that will provide user access to the dataset. | -| roles.role | Role | Yes | Name of the IAM role that provides access to the datase. | -| roles.description | Description | No | Description of the IAM role and its permissions. | -| roles.access | Access | No | The type of access provided by the IAM role. | -| roles.firstLevelApprovers | 1st Level Approvers | No | The name(s) of the first-level approver(s) of the role. | -| roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role. | +| Key | UX label | Required | Description | +|----------------------------|---------------------|----------|----------------------------------------------------------------------| +| roles | Roles | No | Array. A list of roles that will provide user access to the dataset. | +| roles.role | Role | Yes | Name of the IAM role that provides access to the dataset. | +| roles.description | Description | No | Description of the IAM role and its permissions. | +| roles.access | Access | No | The type of access provided by the IAM role. | +| roles.firstLevelApprovers | 1st Level Approvers | No | The name(s) of the first-level approver(s) of the role. | +| roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role. | ## Service-Level Agreement (SLA) @@ -594,16 +593,16 @@ slaProperties: ### Definitions -| Key | UX label | Required | Description | -|------------------------|------------------------|--------------------------------|----------------------------------------------------------------------------------------------------------------------------| -| slaDefaultElement | Default SLA element(s) | No | Element (using the element path notation) to do the checks on. | -| slaProperties | SLA | No | A list of key/value pairs for SLA specific properties. There is no limit on the type of properties. | -| slaProperties.property | Property | Yes | Specific property in SLA, check the Data QoS periodic table. May requires units. | -| slaProperties.value | Value | Yes | Agreement value. The label will change based on the property itself. | -| slaProperties.valueExt | Extended value | No - unless needed by property | Extended agreement value. The label will change based on the property itself. | -| slaProperties.unit | Unit | No - unless needed by property | **d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard. | -| slaProperties.element | Element(s) | No | Element(s) to check on. Multiple elements should be extremely rare and, if so, separated by commas. | -| slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | +| Key | UX label | Required | Description | +|------------------------|------------------------|--------------------------------|-----------------------------------------------------------------------------------------------------| +| slaDefaultElement | Default SLA element(s) | No | Element (using the element path notation) to do the checks on. | +| slaProperties | SLA | No | A list of key/value pairs for SLA specific properties. There is no limit on the type of properties. | +| slaProperties.property | Property | Yes | Specific property in SLA, check the Data QoS periodic table. May requires units. | +| slaProperties.value | Value | Yes | Agreement value. The label will change based on the property itself. | +| slaProperties.valueExt | Extended value | No - unless needed by property | Extended agreement value. The label will change based on the property itself. | +| slaProperties.unit | Unit | No - unless needed by property | **d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard. | +| slaProperties.element | Element(s) | No | Element(s) to check on. Multiple elements should be extremely rare and, if so, separated by commas. | +| slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | ## Infrastructure & servers TBD @@ -644,9 +643,9 @@ contractCreatedTs: 2022-11-15 02:59:43 ### Other properties definition -| Key | UX label | Required | Description | -|---------------------------|----------------------|----------|-------------------------------------------------------------------------------------------------------------------| -| contractCreatedTs | Contract Created UTC | No | Timestamp in UTC of when the data contract was created. | +| Key | UX label | Required | Description | +|---------------------------|----------------------|----------|--------------------------------------------------------------| +| contractCreatedTs | Contract Created UTC | No | Timestamp in UTC of when the data contract was created. | ## Full example diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 81cce37..51b470f 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -18,21 +18,15 @@ "type": "string", "default": "v3.0.0", "description": "Version of the standard used to build data contract. Default value is v3.0.0.", - "pattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+" + "enum": ["v3.0.0", "v2.2.2", "v2.2.1", "v2.2.0"] }, - "uuid": { + "id": { "type": "string", - "description": "A unique identifier used to reduce the risk of dataset name collisions; initially the UUID will be created using a UUID generator tool ([example](https://www.uuidgenerator.net/)). However, we may want to develop a method that accepts a seed value using a combination of fields–such as name, kind and source–to create a repeatable value." + "description": "A unique identifier used to reduce the risk of dataset name collisions, such as a UUID." }, - "datasetKind": { + "name": { "type": "string", - "description": "The kind of dataset being cataloged; Expected values are `virtualDataset` or `managedDataset`.", - "examples": ["virtualDataset", "managedDataset"] - }, - "userConsumptionMode": { - "type": "string", - "description": "List of data modes for which the dataset may be used. Expected sample values might be `analytical` or `operational`.
Note: in the future, this will probably be replaced by ports.", - "examples": ["analytical", "operational"] + "description": "Name of the data contract." }, "type": { "type": "string", @@ -44,202 +38,1398 @@ "description": "Indicates the property the data is primarily associated with. Value is case insensitive." }, "tags": { + "$ref": "#/$defs/Tags" + }, + "status": { + "type": "string", + "description": "Current status of the dataset. Valid values are `production`, `test`, or `development`.", + "examples": ["production", "test", "development"] + }, + "servers": { "type": "array", - "description": "A list of tags that may be assigned to the dataset, table or column; the `tags` keyword may appear at any level.", + "description": "List of servers where the datasets reside.", "items": { - "type": "string" + "$ref": "#/$defs/Server" + } + }, + "dataProduct": { + "type": "string", + "description": "The name of the data product." + }, + "description": { + "type": "object", + "description": "High level description of the dataset.", + "properties": { + "usage": { + "type": "string", + "description": "Intended usage of the dataset." + }, + "purpose": { + "type": "string", + "description": "Purpose of the dataset." + }, + "limitations": { + "type": "string", + "description": "Limitations of the dataset." + } + } + }, + "domain": { + "type": "string", + "description": "Name of the logical data domain.", + "examples": ["imdb_ds_aggregate", "receiver_profile_out", "transaction_profile_out"] + }, + "schema": { + "type": "array", + "description": "A list of elements within the schema to be cataloged.", + "items": { + "$ref": "#/$defs/SchemaObject" + } + }, + "support": { + "$ref": "#/$defs/Support" + }, + "price": { + "$ref": "#/$defs/Pricing" + }, + "team": { + "type": "array", + "items": { + "$ref": "#/$defs/Team" + } + }, + "roles": { + "type": "array", + "description": "A list of roles that will provide user access to the dataset.", + "items": { + "$ref": "#/$defs/Role" + } + }, + "slaDefaultElement": { + "type": "string", + "description": "Element (using the element path notation) to do the checks on." + }, + "slaProperties": { + "type": "array", + "description": "A list of key/value pairs for SLA specific properties. There is no limit on the type of properties (more details to come).", + "items": { + "$ref": "#/$defs/ServiceLevelAgreementProperty" + } + }, + "customProperties": { + "$ref": "#/$defs/CustomProperties" + }, + "contractCreatedTs": { + "type": "string", + "format": "date-time", + "description": "Timestamp in UTC of when the data contract was created." + } + }, + "required": ["version", "apiVersion", "kind", "id", "status"], + "additionalProperties": false, + "$defs": { + "Server": { + "type": "object", + "description": "Data source details of where data is physically stored.", + "properties": { + "server": { + "type": "string", + "description": "Identifier of the server." + }, + "type": { + "type": "string", + "description": "Type of the server.", + "enum": [ + "athena", "azure", "bigquery", "clickhouse", "databricks", "denodo", "dremio", + "duckdb", "glue", "googlecloudsql", "ibmdb2", "kafka", "kinesis", "local", "mssql", + "mysql", "oracle", "postgres", "presto", "pubsub", + "redshift", "s3", "sftp", "snowflake", "sqlserver", "synapse", "trino", "vertica" + ] + }, + "description": { + "type": "string", + "description": "Description of the server." + }, + "environment": { + "type": "string", + "description": "Environment of the server.", + "examples": ["prod", "preprod", "dev", "uat"] + }, + "roles": { + "type": "array", + "description": "List of roles that have access to the server.", + "items": { + "$ref": "#/$defs/Role" + } + }, + "customProperties": { + "$ref": "#/$defs/CustomProperties" + } + }, + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "athena" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/AthenaServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "azure" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/AzureServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "bigquery" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/BigQueryServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "clickhouse" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/ClickHouseServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "databricks" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/DatabricksServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "denodo" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/DenodoServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "dremio" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/DremioServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "duckdb" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/DuckdbServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "glue" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/GlueServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "googlecloudsql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/GoogleCloudSqlServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "ibmdb2" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/IBMDB2Server" + } + }, + { + "if": { + "properties": { + "type": { + "const": "kafka" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/KafkaServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "kinesis" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/KinesisServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "local" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/LocalServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "mssql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/MSSqlServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "mysql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/MySqlServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "oracle" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/OracleServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "postgres" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/PostgresServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "presto" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/PrestoServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "pubsub" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/PubSubServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "redshift" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/RedshiftServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "s3" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/S3Server" + } + }, + { + "if": { + "properties": { + "type": { + "const": "sftp" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/SftpServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "snowflake" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/SnowflakeServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "sqlserver" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/SqlserverServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "synapse" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/SynapseServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "trino" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/TrinoServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "vertica" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/VerticaServer" + } + } + ], + "required": ["server", "type"] + }, + "ServerSource": { + "AthenaServer": { + "type": "object", + "title": "AthenaServer", + "properties": { + "stagingDir": { + "type": "string", + "format": "uri", + "description": "Amazon Athena automatically stores query results and metadata information for each query that runs in a query result location that you can specify in Amazon S3.", + "examples": [ + "s3://my_storage_account_name/my_container/path" + ] + }, + "schema": { + "type": "string", + "description": "Identify the schema in the data source in which your tables exist." + }, + "catalog": { + "type": "string", + "description": "Identify the name of the Data Source, also referred to as a Catalog.", + "default": "awsdatacatalog" + }, + "regionName": { + "type": "string", + "description": "The region your AWS account uses.", + "examples": ["eu-west-1"] + } + }, + "required": [ + "staging_dir", + "schema" + ] + }, + "AzureServer": { + "type": "object", + "title": "AzureServer", + "properties": { + "location": { + "type": "string", + "format": "uri", + "description": "Fully qualified path to Azure Blob Storage or Azure Data Lake Storage (ADLS), supports globs.", + "examples": [ + "az://my_storage_account_name.blob.core.windows.net/my_container/path/*.parquet", + "abfss://my_storage_account_name.dfs.core.windows.net/my_container_name/path/*.parquet" + ] + }, + "format": { + "type": "string", + "enum": [ + "parquet", + "delta", + "json", + "csv" + ], + "description": "File format." + }, + "delimiter": { + "type": "string", + "enum": [ + "new_line", + "array" + ], + "description": "Only for format = json. How multiple json documents are delimited within one file" + } + }, + "required": [ + "location", + "format" + ] + }, + "BigQueryServer": { + "type": "object", + "title": "BigQueryServer", + "properties": { + "project": { + "type": "string", + "description": "The GCP project name." + }, + "dataset": { + "type": "string", + "description": "The GCP dataset name." + } + }, + "required": [ + "project", + "dataset" + ] + }, + "ClickHouseServer": { + "type": "object", + "title": "ClickHouseServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the ClickHouse server." + }, + "port": { + "type": "integer", + "description": "The port to the ClickHouse server." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "port", + "database" + ] + }, + "DatabricksServer": { + "type": "object", + "title": "DatabricksServer", + "properties": { + "host": { + "type": "string", + "description": "The Databricks host", + "examples": [ + "dbc-abcdefgh-1234.cloud.databricks.com" + ] + }, + "catalog": { + "type": "string", + "description": "The name of the Hive or Unity catalog" + }, + "schema": { + "type": "string", + "description": "The schema name in the catalog" + } + }, + "required": [ + "catalog", + "schema" + ] + }, + "DenodoServer": { + "type": "object", + "title": "DenodoServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Denodo server." + }, + "port": { + "type": "integer", + "description": "The port of the Denodo server." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "port" + ] + }, + "DremioServer": { + "type": "object", + "title": "DremioServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Dremio server." + }, + "port": { + "type": "integer", + "description": "The port of the Dremio server." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + } + }, + "required": [ + "host", + "port" + ] + }, + "DuckdbServer": { + "type": "object", + "title": "DuckdbServer", + "properties": { + "database": { + "type": "string", + "description": "Path to duckdb database file." + }, + "schema": { + "type": "integer", + "description": "The name of the schema." + } + }, + "required": [ + "database" + ] + }, + "GlueServer": { + "type": "object", + "title": "GlueServer", + "properties": { + "account": { + "type": "string", + "description": "The AWS Glue account", + "examples": [ + "1234-5678-9012" + ] + }, + "database": { + "type": "string", + "description": "The AWS Glue database name", + "examples": [ + "my_database" + ] + }, + "location": { + "type": "string", + "format": "uri", + "description": "The AWS S3 path. Must be in the form of a URL.", + "examples": [ + "s3://datacontract-example-orders-latest/data/{model}" + ] + }, + "format": { + "type": "string", + "description": "The format of the files", + "examples": [ + "parquet", + "csv", + "json", + "delta" + ] + } + }, + "required": [ + "account", + "database" + ] + }, + "GoogleCloudSqlServer": { + "type": "object", + "title": "GoogleCloudSqlServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Google Cloud Sql server." + }, + "port": { + "type": "integer", + "description": "The port of the Google Cloud Sql server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + } + }, + "required": [ + "host", + "port", + "database", + "schema" + ] + }, + "IBMDB2Server": { + "type": "object", + "title": "IBMDB2Server", + "properties": { + "host": { + "type": "string", + "description": "The host of the IBM DB2 server." + }, + "port": { + "type": "integer", + "description": "The port of the IBM DB2 server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + } + }, + "required": [ + "host", + "port", + "database" + ] + }, + "KafkaServer": { + "type": "object", + "title": "KafkaServer", + "description": "Kafka Server", + "properties": { + "host": { + "type": "string", + "description": "The bootstrap server of the kafka cluster." + }, + "topic": { + "type": "string", + "description": "The topic name." + }, + "format": { + "type": "string", + "description": "The format of the messages.", + "examples": ["json", "avro", "protobuf", "xml"], + "default": "json" + } + }, + "required": [ + "host", + "topic" + ] + }, + "KinesisServer": { + "type": "object", + "title": "KinesisDataStreamsServer", + "description": "Kinesis Data Streams Server", + "properties": { + "stream": { + "type": "string", + "description": "The name of the Kinesis data stream." + }, + "region": { + "type": "string", + "description": "AWS region.", + "examples": [ + "eu-west-1" + ] + }, + "format": { + "type": "string", + "description": "The format of the record", + "examples": [ + "json", + "avro", + "protobuf" + ] + } + }, + "required": [ + "stream" + ] + }, + "LocalServer": { + "type": "object", + "title": "LocalServer", + "properties": { + "path": { + "type": "string", + "description": "The relative or absolute path to the data file(s).", + "examples": [ + "./folder/data.parquet", + "./folder/*.parquet" + ] + }, + "format": { + "type": "string", + "description": "The format of the file(s)", + "examples": [ + "json", + "parquet", + "delta", + "csv" + ] + } + }, + "required": [ + "path", + "format" + ] + }, + "MSSqlServer": { + "type": "object", + "title": "MSSqlServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the MS Sql server." + }, + "port": { + "type": "integer", + "description": "The port of the MS Sql server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + }, + "driver": { + "type": "string", + "description": "Version of ODBC driver to use." + } + }, + "required": [ + "host", + "port", + "database", + "schema" + ] + }, + "MySqlServer": { + "type": "object", + "title": "MySqlServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the MySql server." + }, + "port": { + "type": "integer", + "description": "The port of the MySql server." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "port", + "database" + ] + }, + "OracleServer": { + "type": "object", + "title": "OracleServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the oracle server", + "examples": [ + "localhost" + ] + }, + "port": { + "type": "integer", + "description": "The port to the oracle server.", + "examples": [ + 1523 + ] + }, + "serviceName": { + "type": "string", + "description": "The name of the service.", + "examples": [ + "service" + ] + } + }, + "required": [ + "host", + "port", + "serviceName" + ] + }, + "PostgresServer": { + "type": "object", + "title": "PostgresServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the Postgres server" + }, + "port": { + "type": "integer", + "description": "The port to the Postgres server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema in the database." + } + }, + "required": [ + "host", + "port", + "database", + "schema" + ] + }, + "PrestoServer": { + "type": "object", + "title": "PrestoServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the Presto server", + "examples": [ + "localhost:8080" + ] + }, + "catalog": { + "type": "string", + "description": "The name of the catalog.", + "examples": [ + "postgres" + ] + }, + "schema": { + "type": "string", + "description": "The name of the schema.", + "examples": [ + "public" + ] + } + }, + "required": [ + "host" + ] + }, + "PubSubServer": { + "type": "object", + "title": "PubSubServer", + "properties": { + "project": { + "type": "string", + "description": "The GCP project name." + }, + "topic": { + "type": "string", + "description": "The topic name." + } + }, + "required": [ + "project", + "topic" + ] + }, + "RedshiftServer": { + "type": "object", + "title": "RedshiftServer", + "properties": { + "host": { + "type": "string", + "description": "An optional string describing the server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + }, + "region": { + "type": "string", + "description": "AWS region of Redshift server.", + "examples": ["us-east-1"] + }, + "account": { + "type": "string", + "description": "The account used by the server." + } + }, + "required": [ + "host", + "database", + "schema" + ] + }, + "S3Server": { + "type": "object", + "title": "S3Server", + "properties": { + "location": { + "type": "string", + "format": "uri", + "description": "S3 URL, starting with `s3://`", + "examples": [ + "s3://datacontract-example-orders-latest/data/{model}/*.json" + ] + }, + "endpointUrl": { + "type": "string", + "format": "uri", + "description": "The server endpoint for S3-compatible servers.", + "examples": ["https://minio.example.com"] + }, + "format": { + "type": "string", + "enum": [ + "parquet", + "delta", + "json", + "csv" + ], + "description": "File format." + }, + "delimiter": { + "type": "string", + "enum": [ + "new_line", + "array" + ], + "description": "Only for format = json. How multiple json documents are delimited within one file" + } + }, + "required": [ + "location" + ] + }, + "SftpServer": { + "type": "object", + "title": "SftpServer", + "properties": { + "location": { + "type": "string", + "format": "uri", + "pattern": "^sftp://.*", + "description": "SFTP URL, starting with `sftp://`", + "examples": [ + "sftp://123.123.12.123/{model}/*.json" + ] + }, + "format": { + "type": "string", + "enum": [ + "parquet", + "delta", + "json", + "csv" + ], + "description": "File format." + }, + "delimiter": { + "type": "string", + "enum": [ + "new_line", + "array" + ], + "description": "Only for format = json. How multiple json documents are delimited within one file" + } + }, + "required": [ + "location" + ] + }, + "SnowflakeServer": { + "type": "object", + "title": "SnowflakeServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the Snowflake server" + }, + "port": { + "type": "integer", + "description": "The port to the Snowflake server." + }, + "account": { + "type": "string", + "description": "The Snowflake account used by the server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + }, + "warehouse": { + "type": "string", + "description": "The name of the cluster of resources that is a Snowflake virtual warehouse." + } + }, + "required": [ + "host", + "port", + "account", + "database", + "warehouse", + "schema" + ] + }, + "SqlserverServer": { + "type": "object", + "title": "SqlserverServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the database server", + "examples": [ + "localhost" + ] + }, + "port": { + "type": "integer", + "description": "The port to the database server.", + "default": 1433, + "examples": [ + 1433 + ] + }, + "database": { + "type": "string", + "description": "The name of the database.", + "examples": [ + "database" + ] + }, + "schema": { + "type": "string", + "description": "The name of the schema in the database.", + "examples": [ + "dbo" + ] + } + }, + "required": [ + "host", + "database", + "schema" + ] + }, + "SynapseServer": { + "type": "object", + "title": "SynapseServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Synapse server." + }, + "port": { + "type": "integer", + "description": "The port of the Synapse server." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "port", + "database" + ] + }, + "TrinoServer": { + "type": "object", + "title": "TrinoServer", + "properties": { + "host": { + "type": "string", + "description": "The Trino host URL.", + "examples": [ + "localhost" + ] + }, + "port": { + "type": "integer", + "description": "The Trino port." + }, + "catalog": { + "type": "string", + "description": "The name of the catalog.", + "examples": [ + "hive" + ] + }, + "schema": { + "type": "string", + "description": "The name of the schema in the database.", + "examples": [ + "my_schema" + ] + } + }, + "required": [ + "host", + "port", + "catalog", + "schema" + ] + }, + "VerticaServer": { + "type": "object", + "title": "VerticaServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Vertica server." + }, + "port": { + "type": "integer", + "description": "The port of the Vertica server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + } + }, + "required": [ + "host", + "port", + "database", + "schema" + ] } }, - "status": { - "type": "string", - "description": "Current status of the dataset. Valid values are `production`, `test`, or `development`.", - "examples": ["production", "test", "development"] - }, - "sourceSystem": { - "type": "string", - "description": "The system where the dataset resides. Expected value can be BigQuery.", - "examples": ["BigQuery"] - }, - "sourcePlatform": { - "type": "string", - "description": "The platform where the dataset resides. Expected value is GoogleCloudPlatform, IBMCloud, Azure...", - "examples": ["GoogleCloudPlatform", "IBMCloud", "Azure", "AWS"] - }, - "server": { - "type": "string", - "description": "The server where the dataset resides." - }, - "quantumName": { - "type": "string", - "description": "The name of the data quantum or data product." - }, - "productSlackChannel": { - "type": "string", - "description": "Slack channel of the team responsible for maintaining the dataset." - }, - "productFeedbackUrl": { - "type": "string", - "description": "The URL for submitting feedback to the team responsible for maintaining the dataset." - }, - "productDl": { - "type": "string", - "description": "The email distribution list (DL) of the persons or team responsible for maintaining the dataset." - }, - "username": { - "type": "string", - "description": "User credentials for connecting to the dataset; how the credentials will be stored/passed is outside of the scope of the contract." - }, - "password": { - "type": "string", - "description": "User credentials for connecting to the dataset; how the credentials will be stored/passed is out of the scope of this contract." - }, - "driverVersion": { - "type": "string", - "description": "The version of the connection driver to be used to connect to the dataset." - }, - "driver": { - "type": "string", - "description": "The connection driver required to connect to the dataset." - }, - "description": { + "SchemaElement": { "type": "object", - "description": "High level description of the dataset.", "properties": { - "usage": { + "name": { "type": "string", - "description": "Intended usage of the dataset." + "description": "Name of the element." }, - "purpose": { + "physicalType": { "type": "string", - "description": "Purpose of the dataset." + "description": "The physical element data type in the data source.", + "examples": ["table", "view", "topic", "file"] }, - "limitations": { + "description": { "type": "string", - "description": "Limitations of the dataset." + "description": "Description of the element." + }, + "businessName": { + "type": "string", + "description": "The business name of the element." + }, + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "tags": { + "$ref": "#/$defs/Tags" } } }, - "project": { - "type": "string", - "description": "Associated project name, can be used for billing or administrative purpose. Used to be datasetProject." - }, - "datasetName": { - "type": "string", - "description": "May be required in cloud instance like GCP BigQuery dataset name." - }, - "datasetDomain": { - "type": "string", - "description": "Name of the logical domain dataset the contract describes. This field is only required for output data contracts.", - "examples": ["imdb_ds_aggregate", "receiver_profile_out", "transaction_profile_out"] - }, - "database": { - "type": "string", - "description": "The database where the dataset resides." - }, - "dataset": { - "type": "array", - "items": { - "$ref": "#/$defs/Dataset" - } - }, - "price": { - "$ref": "#/$defs/Pricing" - }, - "stakeholders": { - "type": "array", - "items": { - "$ref": "#/$defs/Stakeholder" - } - }, - "roles": { - "type": "array", - "description": "A list of roles that will provide user access to the dataset.", - "items": { - "$ref": "#/$defs/Role" - } - }, - "slaDefaultColumn": { - "type": "string", - "description": "Columns (using the Table.Column notation) to do the checks on. By default, it is the partition column." - }, - "slaProperties": { - "type": "array", - "description": "A list of key/value pairs for SLA specific properties. There is no limit on the type of properties (more details to come).", - "items": { - "$ref": "#/$defs/ServiceLevelAgreementProperty" - } - } - }, - "required": ["version", "kind", "uuid", "type", "status", "dataset", "datasetName", "quantumName"], - "$defs": { - "Dataset": { + "SchemaObject": { "type": "object", "properties": { - "table": { + "logicalType": { "type": "string", - "description": "Name of the table being cataloged; the value should only contain the table name. Do not include the project or dataset name in the value." + "description": "The logical element data type.", + "enum": ["object"] }, "physicalName": { "type": "string", - "description": "Physical name of the table, default value is table name + version separated by underscores, as `table_1_2_0`.", + "description": "Physical name.", "examples": ["table_1_2_0"] }, - "priorTableName": { - "type": "string", - "description": "Name of the previous version of the dataset, if applicable." - }, - "description": { - "type": "string", - "description": "Description of the dataset." - }, - "authoritativeDefinitions": { - "$ref": "#/$defs/AuthoritativeDefinitions" - }, - "dataGranularity": { + "dataGranularityDescription": { "type": "string", - "description": "Granular level of the data in the table. Example would be `pmt_txn_id`.", - "examples": ["pmt_txn_id"] + "description": "Granular level of the data in the object.", + "examples": ["Aggregation by country"] }, - "columns": { + "properties": { "type": "array", - "description": "Array. A list of columns in the table.", + "description": "A list of properties for the object.", "items": { - "$ref": "#/$defs/Column" + "$ref": "#/$defs/SchemaProperty" } }, "quality": { - "type": "array", - "description": "Data quality rules with all the relevant information for rule setup and execution.", - "items": { - "$ref": "#/$defs/DataQuality" - } + "$ref": "#/$defs/DataQualityChecks" } }, - "required": ["table"] + "allOf": [ + { + "$ref": "#/$defs/SchemaElement" + } + ], + "required": ["name"], + "unevaluatedProperties": false }, - "Column": { + "SchemaBaseProperty": { "type": "object", "properties": { - "column": { - "type": "string", - "description": "The name of the column." - }, - "isPrimaryKey": { + "primaryKey": { "type": "boolean", - "description": "Boolean value specifying whether the column is primary or not. Default is false." + "description": "Boolean value specifying whether the element is primary or not. Default is false." }, "primaryKeyPosition": { "type": "integer", "default": -1, - "description": "If column is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1." - }, - "businessName": { - "type": "string", - "description": "The business name of the column." + "description": "If element is a primary key, the position of the primary key element. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1." }, "logicalType": { "type": "string", - "description": "The logical column data type.", + "description": "The logical element data type.", "enum": ["string", "date", "number", "integer", "object", "array", "boolean"] }, "logicalTypeOptions": { @@ -248,90 +1438,72 @@ }, "physicalType": { "type": "string", - "description": "The physical column data type in the data source. For example, VARCHAR(2), DOUBLE, INT." - }, - "description": { - "type": "string", - "description": "Description of the column." + "description": "The physical element data type in the data source. For example, VARCHAR(2), DOUBLE, INT." }, - "isNullable": { + "required": { "type": "boolean", "default": false, - "description": "Indicates if the column may contain Null values; possible values are true and false. Default is false." + "description": "Indicates if the element may contain Null values; possible values are true and false. Default is false." }, - "isUnique": { + "unique": { "type": "boolean", "default": false, - "description": "Indicates if the column contains unique values; possible values are true and false. Default is false." + "description": "Indicates if the element contains unique values; possible values are true and false. Default is false." }, - "partitionStatus": { + "partitioned": { "type": "boolean", "default": false, - "description": "Indicates if the column is partitioned; possible values are true and false." + "description": "Indicates if the element is partitioned; possible values are true and false." }, "partitionKeyPosition": { "type": "integer", "default": -1, - "description": "If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1." - }, - "clusterStatus": { - "type": "boolean", - "default": false, - "description": "Indicates of the column is clustered; possible values are true and false." - }, - "clusterKeyPosition": { - "type": "integer", - "default": -1, - "description": "If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1." + "description": "If element is used for partitioning, the position of the partition element. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1." }, "classification": { "type": "string", - "description": "Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5.", + "description": "Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the element; expected values are 1, 2, 3, 4, or 5.", "examples": ["confidential", "restricted", "public"] }, - "authoritativeDefinitions": { - "$ref": "#/$defs/AuthoritativeDefinitions" - }, - "encryptedColumnName": { + "encryptedName": { "type": "string", - "description": "The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`." + "description": "The element name within the dataset that contains the encrypted element value. For example, unencrypted element `email_address` might have an encryptedName of `email_address_encrypt`." }, - "transformSourceTables": { + "transformSourceObjects": { "type": "array", - "description": "List of sources used in column transformation.", + "description": "List of objects in the data source used in the transformation.", "items": { "type": "string" } }, "transformLogic": { "type": "string", - "description": "Logic used in the column transformation." + "description": "Logic used in the element transformation." }, "transformDescription": { "type": "string", "description": "Describes the transform logic in very simple terms." }, - "sampleValues": { + "examples": { "type": "array", - "description": "List of sample column values.", + "description": "List of sample element values.", "items": { - "type": "string" + "$ref": "#/$defs/AnyType" } }, - "criticalDataElementStatus": { + "criticalDataElement": { "type": "boolean", "default": false, "description": "True or false indicator; If element is considered a critical data element (CDE) then true else false." }, - "tags": { - "type": "array", - "description": "A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level.", - "items": { - "type": "string" - } + "quality": { + "$ref": "#/$defs/DataQualityChecks" } }, "allOf": [ + { + "$ref": "#/$defs/SchemaElement" + }, { "if": { "properties": { @@ -343,6 +1515,7 @@ "then": { "properties": { "logicalTypeOptions": { + "type": "object", "properties": { "minLength": { "type": "integer", @@ -356,7 +1529,6 @@ }, "pattern": { "type": "string", - "format": "regex", "description": "Regular expression pattern to define valid value. Follows regular expression syntax from ECMA-262 (https://262.ecma-international.org/5.1/#sec-15.10.1)." }, "format": { @@ -369,7 +1541,8 @@ } } } - }, { + }, + { "if": { "properties": { "logicalType": { @@ -380,6 +1553,7 @@ "then": { "properties": { "logicalTypeOptions": { + "type": "object", "properties": { "format": { "type": "string", @@ -425,6 +1599,7 @@ "then": { "properties": { "logicalTypeOptions": { + "type": "object", "properties": { "multipleOf": { "type": "number", @@ -476,6 +1651,7 @@ "then": { "properties": { "logicalTypeOptions": { + "type": "object", "properties": { "multipleOf": { "type": "number", @@ -523,6 +1699,7 @@ "then": { "properties": { "logicalTypeOptions": { + "type": "object", "properties": { "maxProperties": { "type": "integer", @@ -561,6 +1738,7 @@ "then": { "properties": { "logicalTypeOptions": { + "type": "object", "properties": { "maxItems": { "type": "integer", @@ -580,12 +1758,42 @@ } }, "additionalProperties": false + }, + "items": { + "$ref": "#/$defs/SchemaItemProperty", + "description": "List of items in an array (only applicable when `logicalType: array`)." } } } } - ], - "required": ["column", "logicalType", "physicalType"] + ] + }, + "SchemaProperty": { + "type": "object", + "$ref": "#/$defs/SchemaBaseProperty", + "required": ["name"], + "unevaluatedProperties": false + }, + "SchemaItemProperty": { + "type": "object", + "$ref": "#/$defs/SchemaBaseProperty", + "properties": { + "properties": { + "type": "array", + "description": "A list of properties for the object.", + "items": { + "$ref": "#/$defs/SchemaProperty" + } + } + }, + "unevaluatedProperties": false + }, + "Tags": { + "type": "array", + "description": "A list of tags that may be assigned to the elements (object or property); the tags keyword may appear at any level.", + "items": { + "type": "string" + } }, "DataQuality": { "type": "object", @@ -648,6 +1856,13 @@ }, "required": ["templateName", "toolName"] }, + "DataQualityChecks": { + "type": "array", + "description": "Data quality rules with all the relevant information for rule setup and execution.", + "items": { + "$ref": "#/$defs/DataQuality" + } + }, "AuthoritativeDefinitions": { "type": "array", "description": "List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", @@ -667,6 +1882,45 @@ "required": ["url", "type"] } }, + "Support": { + "type": "array", + "description": "Top level for support channels.", + "items": { + "$ref": "#/$defs/SupportItem" + } + }, + "SupportItem": { + "type": "object", + "properties": { + "channel": { + "type": "string", + "description": "Channel name or identifier." + }, + "url": { + "type": "string", + "description": "Access URL using normal [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax) (https, mailto, etc.)." + }, + "description": { + "type": "string", + "description": "Description of the channel, free text." + }, + "tool": { + "type": "string", + "description": "Name of the tool, value can be `email`, `slack`, `teams`, `discord`, `ticket`, or `other`.", + "examples": ["email", "slack", "teams", "discord", "ticket", "other"] + }, + "scope": { + "type": "string", + "description": "Scope can be: `interactive`, `announcements`, `issues`.", + "examples": ["interactive", "announcements", "issues"] + }, + "invitationUrl": { + "type": "string", + "description": "Some tools uses invitation URL for requesting or subscribing. Follows the [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax)." + } + }, + "required": ["channel", "url"] + }, "Pricing": { "type": "object", "properties": { @@ -684,28 +1938,30 @@ } } }, - "Stakeholder": { + "Team": { "type": "object", "properties": { "username": { "type": "string", - "description": "The stakeholder's username or email." + "description": "The team's username or email." }, "role": { "type": "string", - "description": "The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role." + "description": "The team's job role; Examples might be owner, data steward. There is no limit on the role." }, "dateIn": { "type": "string", - "description": "The date when the user became a stakeholder." + "format": "date", + "description": "The date when the user became a team." }, "dateOut": { "type": "string", - "description": "The date when the user ceased to be a stakeholder" + "format": "date", + "description": "The date when the user ceased to be a team" }, "replacedByUsername": { "type": "string", - "description": "The username of the user who replaced the stakeholder" + "description": "The username of the user who replaced the team" } } }, @@ -714,22 +1970,26 @@ "properties": { "role": { "type": "string", - "description": "Name of the IAM role that provides access to the dataset; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + "description": "Name of the IAM role that provides access to the dataset." + }, + "description": { + "type": "string", + "description": "Description of the IAM role and its permissions." }, "access": { "type": "string", - "description": "The type of access provided by the IAM role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + "description": "The type of access provided by the IAM role." }, "firstLevelApprovers": { "type": "string", - "description": "The name(s) of the first level approver(s) of the role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + "description": "The name(s) of the first-level approver(s) of the role." }, "secondLevelApprovers": { "type": "string", - "description": "The name(s) of the second level approver(s) of the role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + "description": "The name(s) of the second-level approver(s) of the role." } }, - "required": ["role", "access"] + "required": ["role"] }, "ServiceLevelAgreementProperty": { "type": "object", @@ -739,34 +1999,36 @@ "description": "Specific property in SLA, check the periodic table. May requires units (more details to come)." }, "value": { - "oneOf": [ + "anyOf": [ { "type": "string" }, { "type": "number" - } - ], - "description": "Agreement value. The label will change based on the property itself." - }, - "valueExt": { - "oneOf": [ + }, { - "type": "string" + "type": "integer" }, { - "type": "number" + "type": "boolean" + }, + { + "type": "null" } ], + "description": "Agreement value. The label will change based on the property itself." + }, + "valueExt": { + "$ref": "#/$defs/AnyNonCollectionType", "description": "Extended agreement value. The label will change based on the property itself." }, "unit": { "type": "string", "description": "**d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard." }, - "column": { + "element": { "type": "string", - "description": "Column(s) to check on. Multiple columns should be extremely rare and, if so, separated by commas." + "description": "Element(s) to check on. Multiple elements should be extremely rare and, if so, separated by commas." }, "driver": { "type": "string", @@ -776,6 +2038,13 @@ }, "required": ["property", "value"] }, + "CustomProperties": { + "type": "array", + "description": "A list of key/value pairs for custom properties.", + "items": { + "$ref": "#/$defs/CustomProperty" + } + }, "CustomProperty": { "type": "object", "properties": { @@ -784,10 +2053,54 @@ "description": "The name of the key. Names should be in camel case–the same as if they were permanent properties in the contract." }, "value": { - "type": "object", + "$ref": "#/$defs/AnyType", "description": "The value of the key." } } + }, + "AnyType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "integer" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ] + }, + "AnyNonCollectionType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "integer" + }, + { + "type": "boolean" + }, + { + "type": "null" + } + ] } } } \ No newline at end of file diff --git a/script/validate-examples.sh b/script/validate-examples.sh new file mode 100644 index 0000000..f344f6c --- /dev/null +++ b/script/validate-examples.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +LIGHT_BLUE='\033[1;34m' +NC='\033[0m' + +script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +json_schema_version=${JSON_SCHEMA_VERSION:-v3.0.0} +num_failed_validation=0 + +echo "Checking if $json_schema_version JSON schema is valid" +if ajv compile --spec=draft2019 -c ajv-formats -s "${script_dir}/../schema/odcs-json-schema-${json_schema_version}.json"; then + echo -e "${GREEN}Valid JSON schema${NC}" +else + echo -e "${RED}Invalid JSON schema, exiting${NC}" + exit 1 +fi + +echo -e "Validating example ODCS files based on ${json_schema_version} JSON schema" +for file in docs/examples/*/*.yaml; do + if ajv validate --spec=draft2019 -c ajv-formats -s "${script_dir}/../schema/odcs-json-schema-${json_schema_version}.json" -d "${script_dir}/../${file}"; then + echo -e "${GREEN}Passed validation, file=${file}${NC}" + else + num_failed_validation=$((num_failed_validation+1)) + fi +done + +echo -e "${YELLOW}Total failed=${num_failed_validation}${NC}" +if [ "${num_failed_validation}" -gt 0 ]; then + exit 1 +else + exit 0 +fi From f8b1a1804b09f59e5ca158c42f8d54aa9b480f23 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Wed, 21 Aug 2024 14:18:19 +0800 Subject: [PATCH 22/93] Add in RFC-0007 data quality base definition to JSON schema --- docs/examples/all/full-example.odcs.yaml | 29 ++-- .../quality/column-accuracy.odcs.yaml | 4 +- .../quality/column-completeness.odcs.yaml | 5 +- docs/examples/quality/column-custom.odcs.yaml | 45 ++++++ .../quality/column-validity.odcs.yaml | 5 +- schema/odcs-json-schema-v3.0.0.json | 136 ++++++++++++++---- 6 files changed, 173 insertions(+), 51 deletions(-) create mode 100644 docs/examples/quality/column-custom.odcs.yaml diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index e13f00d..09362f0 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -95,16 +95,14 @@ schema: type: implementation encryptedName: rcvr_cntry_code_encrypted quality: - - code: nullCheck - templateName: NullCheck + - rule: nullCheck description: column should not contain null values - toolName: Elevate - toolRuleName: DQ.rw.tab1_2_0_0.rcvr_cntry_code.NullCheck dimension: completeness # dropdown 7 values - type: dataQuality + type: predefined severity: error businessImpact: operational - scheduleCronExpression: 0 20 * * * + schedule: 0 20 * * * + scheduler: cron customProperties: - property: FIELD_NAME value: @@ -113,16 +111,15 @@ schema: - property: COMPARISON_TYPE value: Greater than quality: - - code: countCheck # Required, name of the rule - templateName: CountCheck # NEW in v2.1.0 Required - description: Ensure row count is within expected volume range # Optional - toolName: Elevate # Required - toolRuleName: DQ.rw.tab1.CountCheck # NEW in v2.1.0 Optional (Available only to the users who can change in source code edition) - dimension: completeness # Optional - type: reconciliation # Optional NEW in v2.1.0 default value for column level check - dataQuality and for table level reconciliation - severity: error # Optional NEW in v2.1.0, default value is error - businessImpact: operational # Optional NEW in v2.1.0 - scheduleCronExpression: 0 20 * * * # Optional NEW in v2.1.0 default schedule - every day 10 a.m. UTC + - rule: countCheck + type: predefined + description: Ensure row count is within expected volume range + dimension: completeness + method: reconciliation + severity: error + businessImpact: operational + schedule: 0 20 * * * + scheduler: cron # Pricing price: diff --git a/docs/examples/quality/column-accuracy.odcs.yaml b/docs/examples/quality/column-accuracy.odcs.yaml index b29e182..bcec5d8 100644 --- a/docs/examples/quality/column-accuracy.odcs.yaml +++ b/docs/examples/quality/column-accuracy.odcs.yaml @@ -19,8 +19,8 @@ schema: logicalType: number physicalType: float(3,2) quality: - - templateName: RangeCheck - toolName: ClimateQuantumDataQualityPackage + - type: predefined + rule: between description: 'This name should contain positive values under 500' dimension: accuracy severity: error diff --git a/docs/examples/quality/column-completeness.odcs.yaml b/docs/examples/quality/column-completeness.odcs.yaml index 15f7376..a28ea5e 100644 --- a/docs/examples/quality/column-completeness.odcs.yaml +++ b/docs/examples/quality/column-completeness.odcs.yaml @@ -20,9 +20,8 @@ schema: logicalType: number physicalType: int quality: - - templateName: NullCheck - toolName: ClimateQuantumDataQualityPackage - description: This column should not contain null values + - description: This column should not contain null values dimension: completeness severity: error + rule: nullCheck businessImpact: operational \ No newline at end of file diff --git a/docs/examples/quality/column-custom.odcs.yaml b/docs/examples/quality/column-custom.odcs.yaml new file mode 100644 index 0000000..c73f1de --- /dev/null +++ b/docs/examples/quality/column-custom.odcs.yaml @@ -0,0 +1,45 @@ +version: 1.0.0 +apiVersion: v3.0.0 +kind: DataContract +id: 53581432-6c55-4ba2-a65f-72344a91553a +type: tables +status: current +name: my_table +dataProduct: my_quantum +schema: + - name: Air_Quality + description: Air quality of the city of New York + authoritativeDefinitions: + - url: https://catalog.data.gov/dataset/air-quality + type: Reference definition on Data.gov + dataGranularityDescription: Raw records + properties: + - name: UniqueID + primaryKey: true + businessName: Unique identifier + logicalType: number + physicalType: int + quality: + - type: custom + description: This column should not contain values under 100000 + dimension: conformity + severity: error + businessImpact: operational + engine: soda + implementation: | + type: duplicate_percent + columns: + - carrier + - shipment_numer + must_be_less_than: 1.0 + - type: custom + dimension: uniqueness + severity: error + businessImpact: operational + engine: soda + implementation: + type: duplicate_percent + columns: + - carrier + - shipment_numer + must_be_less_than: 1.0 diff --git a/docs/examples/quality/column-validity.odcs.yaml b/docs/examples/quality/column-validity.odcs.yaml index 3c686fd..98bf26a 100644 --- a/docs/examples/quality/column-validity.odcs.yaml +++ b/docs/examples/quality/column-validity.odcs.yaml @@ -20,10 +20,9 @@ schema: logicalType: number physicalType: int quality: - - templateName: RangeCheck - toolName: ClimateQuantumDataQualityPackage + - rule: minCheck description: This column should not contain values under 100000 - dimension: validity + dimension: conformity severity: error businessImpact: operational customProperties: diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 51b470f..51f445b 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -1798,53 +1798,54 @@ "DataQuality": { "type": "object", "properties": { - "code": { + "type": { "type": "string", - "description": "The Rosewall data quality code(s) indicating which quality checks need to be performed at the dataset, table or column level; The quality keyword may appear at any level; Some quality checks require parameters such so the check can be completed (eg, list of fields used to identify a distinct row) therefore some quality checks may be followed by a single value or an array; See appendix for link to quality checks." + "description": "The type of quality check.", + "enum": ["text", "predefined", "sql", "custom"], + "default": "predefined" }, - "templateName": { + "name": { "type": "string", - "description": "The template name which indicates what is the equivalent template from the tool." + "description": "Name of the data quality check." }, "description": { "type": "string", "description": "Describe the quality check to be completed." }, - "toolName": { - "type": "string", - "description": "Name of the tool used to complete the quality check; Most will be Elevate initially." - }, - "toolRuleName": { - "type": "string", - "description": "Name of the quality tool's rule created to complete the quality check." - }, "dimension": { "type": "string", - "description": "The key performance indicator (KPI) or dimension for data quality." + "description": "The key performance indicator (KPI) or dimension for data quality.", + "enum": ["accuracy", "completeness", "conformity", "consistency", "coverage", "timeliness", "uniqueness"] }, - "columns": { + "severity": { "type": "string", - "description": "List of columns to be used in the quality check." + "description": "The severance of the quality rule.", + "examples": ["info", "warning", "error"] }, - "column": { + "businessImpact": { "type": "string", - "description": "To be used in lieu of quality.columns when only a single column is required for the quality check." + "description": "Consequences of the rule failure.", + "examples": ["operational", "regulatory"] }, - "type": { + "method": { "type": "string", - "description": "The type of quality check." + "examples": ["reconciliation"] }, - "severity": { + "schedule": { "type": "string", - "description": "The severance of the quality rule." + "description": "Rule execution schedule details.", + "examples": ["0 20 * * *"] }, - "businessImpact": { + "scheduler": { "type": "string", - "description": "Consequences of the rule failure." + "description": "The name or type of scheduler used to start the data quality check.", + "examples": ["cron"] }, - "scheduleCronExpression": { - "type": "string", - "description": "Rule execution schedule details." + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "tags": { + "$ref": "#/$defs/Tags" }, "customProperties": { "type": "array", @@ -1854,7 +1855,46 @@ } } }, - "required": ["templateName", "toolName"] + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "predefined" + } + } + }, + "then": { + "$ref": "#/$defs/DataQualityPredefined" + } + }, + { + "if": { + "properties": { + "type": { + "const": "sql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/DataQualitySql" + } + }, + { + "if": { + "properties": { + "type": { + "const": "custom" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/DataQualityCustom" + } + } + ] }, "DataQualityChecks": { "type": "array", @@ -1863,6 +1903,48 @@ "$ref": "#/$defs/DataQuality" } }, + "DataQualityPredefined": { + "type": "object", + "properties": { + "rule": { + "type": "string", + "description": "Define a data quality check based on the predefined rules as per ODCS." + } + }, + "required": ["rule"] + }, + "DataQualitySql": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Query string that adheres to the dialect of the provided server.", + "examples": ["SELECT COUNT(*) FROM ${table} WHERE ${column} IS NOT NULL"] + } + }, + "required": ["query"] + }, + "DataQualityCustom": { + "type": "object", + "properties": { + "engine": { + "type": "string", + "description": "Name of the engine which executes the data quality checks.", + "examples": ["soda", "great-expectations", "monte-carlo", "dbt"] + }, + "implementation": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "required": ["engine", "implementation"] + }, "AuthoritativeDefinitions": { "type": "array", "description": "List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", From 8192640b35bb5fb5917c2e1bd286e9b4db1c2ae2 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 28 Aug 2024 20:58:09 +0200 Subject: [PATCH 23/93] Add properties key to logicalType object for nested fields. --- schema/odcs-json-schema-v3.0.0.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 51f445b..1d0c822 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -1723,6 +1723,13 @@ } }, "additionalProperties": false + }, + "properties": { + "type": "array", + "description": "A list of properties for the object.", + "items": { + "$ref": "#/$defs/SchemaProperty" + } } } } From a383839b636dadc72b4a3a7887fe74fbe4368018 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Thu, 29 Aug 2024 11:05:21 -0400 Subject: [PATCH 24/93] Rename standard.md to index.md --- docs/{standard.md => index.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{standard.md => index.md} (100%) diff --git a/docs/standard.md b/docs/index.md similarity index 100% rename from docs/standard.md rename to docs/index.md From a35bf5e08015de49ef2f5e963a0b82a9bd0c27e2 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Thu, 29 Aug 2024 11:05:50 -0400 Subject: [PATCH 25/93] Rename index.md to README.md --- docs/{index.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{index.md => README.md} (100%) diff --git a/docs/index.md b/docs/README.md similarity index 100% rename from docs/index.md rename to docs/README.md From 1ef6335abea790396d973142a31f490487429fdb Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Thu, 29 Aug 2024 14:00:03 -0400 Subject: [PATCH 26/93] Update README.md Added name and email as part of the team member. --- docs/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/README.md b/docs/README.md index 98c2ef9..74c655f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -497,6 +497,7 @@ team: - username: daustin role: Owner comment: Keeper of the grail + name: David Austin dateIn: 2022-10-01 ``` @@ -510,6 +511,8 @@ The UX label is the label used in the UI and other user experiences. It is not l | team.role | Role | No | The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role. | | team.dateIn | Date In | No | The date when the user became a stakeholder. | | team.dateOut | Date Out | No | The date when the user ceased to be a stakeholder | +| team.name | Full Name | No | Full name. | +| team.email | Email | No | Explicit email. | | team.replacedByUsername | Replaced By | No | The username of the user who replaced the stakeholder | From 65e488fc4449ee538748cd33092d7aae4aa9ba6f Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Fri, 30 Aug 2024 13:16:57 -0400 Subject: [PATCH 27/93] Update README.md --- docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 98c2ef9..8d95a4d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -73,8 +73,8 @@ tags: null | status | Status | Yes | Current status of the data contract. | | tenant | Tenant | No | Indicates the property the data is primarily associated with. Value is case insensitive. | | domain | Domain | No | Name of the logical data domain. | -| dataProduct | Data Product | No | The name of the data product. | -| description | Description | No | Object. | +| dataProduct | Data Product | No | Name of the data product. | +| description | Description | No | Object containing the descriptions. | | description.purpose | Purpose | No | What is the intended purpose for the provided data. | | description.limitations | Limitations | No | Technical, compliance, and legal limitations for using the data. | | description.usage | Usage | No | How to use the data. | From 3b75a9fdbe916454fb4e0677c1242f9999a12461 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Fri, 30 Aug 2024 13:58:15 -0400 Subject: [PATCH 28/93] Update README.md --- docs/README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/README.md b/docs/README.md index 8d95a4d..371b73d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -73,11 +73,11 @@ tags: null | status | Status | Yes | Current status of the data contract. | | tenant | Tenant | No | Indicates the property the data is primarily associated with. Value is case insensitive. | | domain | Domain | No | Name of the logical data domain. | -| dataProduct | Data Product | No | Name of the data product. | -| description | Description | No | Object containing the descriptions. | -| description.purpose | Purpose | No | What is the intended purpose for the provided data. | -| description.limitations | Limitations | No | Technical, compliance, and legal limitations for using the data. | -| description.usage | Usage | No | How to use the data. | +| dataProduct | Data Product | No | Name of the data product. | +| description | Description | No | Object containing the descriptions. | +| description.purpose | Purpose | No | Intended purpose for the provided data. | +| description.limitations | Limitations | No | Technical, compliance, and legal limitations for data use. | +| description.usage | Usage | No | Recommended usage of the data. | ##
Schema @@ -115,12 +115,9 @@ schema: dataGranularityDescription: Aggregation on columns txn_ref_dt, pmt_txn_id properties: - name: txn_ref_dt - primaryKey: false - primaryKeyPosition: -1 businessName: transaction reference date logicalType: date physicalType: date - required: false description: null partitioned: true partitionKeyPosition: 1 From 09939534015d018989b5562bd601737260fd72c6 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Fri, 30 Aug 2024 13:59:47 -0400 Subject: [PATCH 29/93] Update README.md --- docs/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 74c655f..b65ed55 100644 --- a/docs/README.md +++ b/docs/README.md @@ -512,7 +512,8 @@ The UX label is the label used in the UI and other user experiences. It is not l | team.dateIn | Date In | No | The date when the user became a stakeholder. | | team.dateOut | Date Out | No | The date when the user ceased to be a stakeholder | | team.name | Full Name | No | Full name. | -| team.email | Email | No | Explicit email. | +| team.email | Email | No | Explicit email. | +| team.comment | Comment | No | Generic comment. | | team.replacedByUsername | Replaced By | No | The username of the user who replaced the stakeholder | From 4024b08b789977967d959629d94807bccadca3ad Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 4 Sep 2024 07:06:54 -0400 Subject: [PATCH 30/93] Update database-table-sla.odcs.yaml --- docs/examples/sla/database-table-sla.odcs.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/examples/sla/database-table-sla.odcs.yaml b/docs/examples/sla/database-table-sla.odcs.yaml index 2044afe..7072108 100644 --- a/docs/examples/sla/database-table-sla.odcs.yaml +++ b/docs/examples/sla/database-table-sla.odcs.yaml @@ -13,7 +13,7 @@ slaProperties: - property: latency # Property, see list of values in DP QoS value: 4 unit: d # d, day, days for days; y, yr, years for years - column: tab1.txn_ref_dt # This would not be needed as it is the same table.column as the default one + element: tab1.txn_ref_dt # This would not be needed as it is the same table.column as the default one - property: generalAvailability value: "2022-05-12T09:30:10-08:00" - property: endOfSupport @@ -23,7 +23,7 @@ slaProperties: - property: retention value: 3 unit: y - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt - property: frequency value: 1 valueExt: 1 @@ -31,9 +31,9 @@ slaProperties: column: tab1.txn_ref_dt - property: timeOfAvailability value: 09:00-08:00 - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt driver: regulatory # Describes the importance of the SLA: [regulatory|analytics|operational|...] - property: timeOfAvailability value: 08:00-08:00 - column: tab1.txn_ref_dt - driver: analytics \ No newline at end of file + element: tab1.txn_ref_dt + driver: analytics From bba6fe0c30c3742106719a0923b6e20c83c9d314 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 10 Sep 2024 15:57:09 -0400 Subject: [PATCH 31/93] Update README.md --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 51f7b2f..7365063 100644 --- a/docs/README.md +++ b/docs/README.md @@ -503,7 +503,7 @@ The UX label is the label used in the UI and other user experiences. It is not l | Key | UX label | Required | Description | |-------------------------|--------------------|----------|---------------------------------------------------------------------------------------------------| -| team | Stakeholders | No | Array. | +| team | Team | No | Array. | | team.username | Username | No | The stakeholder's username or email. | | team.role | Role | No | The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role. | | team.dateIn | Date In | No | The date when the user became a stakeholder. | From 8909b32741f16733fc412c85e53431ee5fa69e79 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 10 Sep 2024 16:33:01 -0400 Subject: [PATCH 32/93] Update README.md --- docs/README.md | 231 +++++++++++++++++++++++++++++-------------------- 1 file changed, 135 insertions(+), 96 deletions(-) diff --git a/docs/README.md b/docs/README.md index 7365063..deb7530 100644 --- a/docs/README.md +++ b/docs/README.md @@ -297,111 +297,150 @@ Updated in ODCS (Open Data Contract Standard) v2.2.1. ## Data quality This section describes data quality rules & parameters. They are tightly linked to the schema described in the previous section. -### Example of data quality at the object level +Data quality rules support different levels/stages of data quality attributes: + - __Text__: A human-readable text that describes the quality of the data. + - __Implicit__ rules: A maintained library of commonly-used predefined quality attributes such as `rowCount`, `unique`, `freshness`, and more. + - __SQL__: An individual SQL query that returns a value that can be compared. Can be extended to `Python` or other. + - __Custom__: Quality attributes that are vendor-specific, such as Soda, Great Expectations, dbt tests, or Montecarlo monitors. -Note: -* This example relies on a data quality tool called Elevate. It should be easily transformed to any other tool. If you have questions, please raise an [issue](https://github.com/AIDAUserGroup/open-data-contract-standard/issues). -* The Open Data Contract Standard has a provision for supporting multiple data quality tools. +### Text +A human-readable text that describes the quality of the data. Later in the development process, these might be translated into an executable check (such as `sql`), an implicit rule, or checked through an AI engine. -```YAML -schema: - - name: tab1 - logicalType: object -# ... - quality: - - code: countCheck # Required, name of the rule - templateName: CountCheck # NEW in v2.1.0 Required - description: Ensure row count is within expected volume range # Optional - toolName: Elevate # Required - toolRuleName: DQ.rw.tab1.CountCheck # NEW in v2.1.0 Optional (Available only to the users who can change in source code edition) - dimension: completeness # Optional - type: reconciliation # Optional NEW in v2.1.0 default value for column level check - dataQuality and for table level reconciliation - severity: error # Optional NEW in v2.1.0, default value is error - businessImpact: operational # Optional NEW in v2.1.0 - scheduleCronExpression: 0 20 * * * # Optional NEW in v2.1.0 default schedule - every day 10 a.m. UTC - - code: distinctCheck - description: enforce distinct values - toolName: Elevate - templateName: DistinctCheck - dimension: completeness - toolRuleName: DQ.rw.tab1.DistinctCheck - columns: - - txn_ref_dt - - rcvr_id - column: null - type: reconciliation - severity: error - businessImpact: operational - scheduleCronExpression: 0 20 * * * - customProperties: - - property: FIELD_NAME - value: rcvr_id - - property: FILTER_CONDITIONS - value: 1>0 - - code: piiCheck - description: null - toolName: Elevate - templateName: PIICheck - toolRuleName: DQ.rw.tab1_2_0_0.piiCheck - type: dataQuality - severity: error - businessImpact: operational - scheduleCronExpression: 0 20 * * * - customProperties: - - property: FIELD_NAME - value: - - property: FILTER_CONDITIONS - value: +```yaml +quality: + - type: text + description: The email address was verified by the system. ``` -### Example of data quality at the element level +### Implicit data quality rules +ODCS will provide a set of predefined (or implicit) rules commonly used in data quality checks, designed to be compatible with all major data quality engines. This simplifies the work for data engineers by eliminating the need to manually write SQL queries. -```YAML -schema: - - name: tab1 - logicalType: object - - name: rcvr_id - primaryKey: true # NEW in v2.1.0, Optional, default value is false, indicates whether the column is primary key in the table. - businessName: receiver id -# ... - quality: - - code: nullCheck - templateName: NullCheck - description: column should not contain null values - toolName: Elevate - toolRuleName: DQ.rw.tab1_2_0_0.rcvr_cntry_code.NullCheck - dimension: completeness # dropdown 7 values - type: dataQuality - severity: error - businessImpact: operational - scheduleCronExpression: 0 20 * * * - customProperties: - - property: FIELD_NAME - value: - - property: COMPARE_TO - value: - - property: COMPARISON_TYPE - value: Greater than +#### Property-level +Those examples apply at the property level, such as column, field, etc. + +##### Duplicate count on rows +No more than 10 duplicate names. + +```yaml +quality: +- type: implicit # optional and default value for data quality rules + rule: duplicateCount + mustBeLessThan: 10 + name: Fewer than 10 duplicate names + unit: rows +``` + +##### Duplicate count on % +Duplicates should be less than 1%. + +```yaml +quality: +- rule: duplicateCount + mustBeLessThan: 1 + unit: percent +``` + +##### Valid values +Valid values from a static list. + +```yaml +quality: +- rule: validValues + validValues: ['pounds'] +``` + +#### Object-level +This example applies at the object level (like a table or a view). + +##### Row count +The number of rows must be between 100 and 120. + +```yaml +quality: + - rule: rowCount + mustBeBetween: [100, 120] + name: Verify row count range +``` + +### SQL +A single SQL query that returns either a numeric or boolean value for comparison. The query must be written in the SQL dialect specific to the provided server. + +```yaml +quality: + - type: sql + query: | + SELECT COUNT(*) FROM ${table} WHERE ${column} IS NOT NULL + mustBeLessThan: 3600 +``` + +### Custom +Custom rules allow for vendor-specific checks, including tools like Soda, Great Expectations, dbt-tests, Montecarlo, and others. Any format for properties is acceptable, whether it's written in YAML, JSON, XML, or even uuencoded binary. They are an intermediate step before the vendor accepts ODCS natively. + +#### Soda Example + +```yaml +quality: +- type: custom + engine: soda + implementation: | + type: duplicate_percent # Block + columns: # passed as-is + - carrier # to the tool + - shipment_numer # (Soda in this situation) + must_be_less_than: 1.0 # +``` + +#### Great Expectation Example + +```yaml +quality: +- type: custom + engine: great-expectations + implementation: | + type: expect_table_row_count_to_be_between # Block + kwargs: # passed as-is + minValue: 10000 # to the tool + maxValue: 50000 # (GX in this situation) ``` +### Scheduling +The data contract can contain scheduling information for executing the rules. You can use `schedule` and `scheduler` for those operation. In previous versions of ODCS, the only allowed scheduler was cron and its syntax was `scheduleCronExpression`. + +```yaml +quality: + - type: sql + query: | + SELECT COUNT(*) FROM ${table} WHERE ${column} IS NOT NULL + mustBeLessThan: 3600 + scheduler: cron + schedule: 0 20 * * * +``` + + ### Definitions -| Key | UX label | Required | Description | -|--------------------------------|---------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| quality | Quality | No | Quality tag with all the relevant information for rule setup and execution. | -| quality.code | Quality Code | No | The Rosewall data quality code(s) indicating which quality checks need to be performed at the dataset, table, or column level. The quality keyword may appear at any level. Some quality checks require parameters, so the check can be completed (e.g., a list of fields used to identify a distinct row). Therefore, some quality checks may be followed by a single value or an array. See the appendix for a link to quality checks. | -| quality.templateName | Template Name | Yes | The template name that indicates what is the equivalent template from the tool. | -| quality.description | Description | No | Describe the quality check to be completed. | -| quality.toolName | Tool Name | Yes | Name of the tool used to complete the quality check; Most will be Elevate initially. | -| quality.toolRuleName | Tool Rule Name | No | Name of the quality tool's rule created to complete the quality check. | -| quality.dimension | Dimension | No | The key performance indicator (KPI) or dimension for data quality. | -| quality.columns | Columns | No | List of columns to be used in the quality check. | -| quality.column | Column | No | To be used in lieu of quality.columns when only a single column is required for the quality check. | -| quality.type | Type | No | The type of quality check. | -| quality.severity | Severity | No | The severity of the quality rule. | -| quality.businessImpact | Business Impact | No | Consequences of the rule failure. | -| quality.scheduleCronExpression | Schedule Expression | No | Rule execution schedule details. | -| quality.customProperties | Custom Properties | No | Additional properties required for rule execution. | +|Key |UX label |Required| Description | +|--------------------------------|-------------------------|--------|-------------------------------------------------| +|quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | +|quality.name |Name | No | A short name for the rule. | +|quality.description |Description | No | Describe the quality check to be completed. | +|quality.dimension |Dimension | No | The key performance indicator (KPI) or dimension for data quality. + * `Accuracy` (synonym `Ac`), + * `Completeness` (synonym `Cp`), + * `Conformity` (synonym `Cf`), + * `Consistency` (synonym `Cs`), + * `Coverage` (synonym `Cv`), + * `Timeliness` (synonym `Tm`), + * `Uniqueness` (synonym `Uq`). +| +|quality.method |Method | No | | +|quality.severity |Severity | No | The severity of the quality rule. | +|quality.businessImpact |Business Impact | No | Consequences of the rule failure. | +|quality.customProperties |Custom Properties | No | Additional properties required for rulee xecution. | +|quality.tags |Tags | No | | +|quality.authoritativeDefinitions|Authoritative Definitions| No | | +|quality.scheduler |Scheduler | No | | +|quality.schedule |Scheduler Configuration | No | | ## Support & communication channels From 9b44bdae8628c7ec20676b034e64cb22edc5c19e Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 10 Sep 2024 16:40:56 -0400 Subject: [PATCH 33/93] Update README.md --- docs/README.md | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/docs/README.md b/docs/README.md index deb7530..2c93734 100644 --- a/docs/README.md +++ b/docs/README.md @@ -424,24 +424,34 @@ quality: |quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | |quality.name |Name | No | A short name for the rule. | |quality.description |Description | No | Describe the quality check to be completed. | -|quality.dimension |Dimension | No | The key performance indicator (KPI) or dimension for data quality. - * `Accuracy` (synonym `Ac`), - * `Completeness` (synonym `Cp`), - * `Conformity` (synonym `Cf`), - * `Consistency` (synonym `Cs`), - * `Coverage` (synonym `Cv`), - * `Timeliness` (synonym `Tm`), - * `Uniqueness` (synonym `Uq`). -| +|quality.type | | Yes |Valid values are `implicit` (default), `text`, `sql`, and `custom`. | +|quality.rule | | No | | +|quality. | | No | | +|quality.unit | | No | | +|quality.validValues | | No | | +|quality.query | | No | | +|quality.engine | | No | | +|quality.implementation | | No | | +|quality.dimension |Dimension | No | The key performance indicator (KPI) or dimension for data quality. Valid values are liste after the table.| |quality.method |Method | No | | |quality.severity |Severity | No | The severity of the quality rule. | -|quality.businessImpact |Business Impact | No | Consequences of the rule failure. | +|quality.businessImpact |Business Impact | No | Consequences of the rule failure. | |quality.customProperties |Custom Properties | No | Additional properties required for rulee xecution. | |quality.tags |Tags | No | | |quality.authoritativeDefinitions|Authoritative Definitions| No | | |quality.scheduler |Scheduler | No | | |quality.schedule |Scheduler Configuration | No | | +#### Valid values for dimension + + * `Accuracy` (synonym `Ac`), + * `Completeness` (synonym `Cp`), + * `Conformity` (synonym `Cf`), + * `Consistency` (synonym `Cs`), + * `Coverage` (synonym `Cv`), + * `Timeliness` (synonym `Tm`), + * `Uniqueness` (synonym `Uq`). + ## Support & communication channels Support and communication channels help consumers find help regarding their use of the data contract. In version 3, ODCS opens the From 6828cad9180a2e94b680c20fb4a12ca4fc6b7eca Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 11 Sep 2024 11:32:30 -0400 Subject: [PATCH 34/93] Update README.md --- docs/README.md | 69 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/docs/README.md b/docs/README.md index 2c93734..feb4ab5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -419,30 +419,34 @@ quality: ### Definitions -|Key |UX label |Required| Description | -|--------------------------------|-------------------------|--------|-------------------------------------------------| -|quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | -|quality.name |Name | No | A short name for the rule. | -|quality.description |Description | No | Describe the quality check to be completed. | -|quality.type | | Yes |Valid values are `implicit` (default), `text`, `sql`, and `custom`. | -|quality.rule | | No | | -|quality. | | No | | -|quality.unit | | No | | -|quality.validValues | | No | | -|quality.query | | No | | -|quality.engine | | No | | -|quality.implementation | | No | | -|quality.dimension |Dimension | No | The key performance indicator (KPI) or dimension for data quality. Valid values are liste after the table.| -|quality.method |Method | No | | -|quality.severity |Severity | No | The severity of the quality rule. | -|quality.businessImpact |Business Impact | No | Consequences of the rule failure. | -|quality.customProperties |Custom Properties | No | Additional properties required for rulee xecution. | -|quality.tags |Tags | No | | -|quality.authoritativeDefinitions|Authoritative Definitions| No | | -|quality.scheduler |Scheduler | No | | -|quality.schedule |Scheduler Configuration | No | | - -#### Valid values for dimension +Acronyms: +* DQ: data quality. + +|Key |UX label |Required| Description | +|--------------------------------|--------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | +|quality.name |Name | No | A short name for the rule. | +|quality.description |Description | No | Describe the quality check to be completed. | +|quality.type |Type | No | Type of DQ rule. Valid values are `implicit` (default), `text`, `sql`, and `custom`. | +|quality.rule |Rule name | No | Required for `implicit` DQ rules: the name of the rule to be executed. | +|quality.\ |See below | No | Multiple values are allowed for the **property**, the value is the one to compare to. | +|quality.unit |Unit | No | Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed. | +|quality.validValues |Valid values | No | Static list of valid values. | +|quality.query |SQL Query | No | Required for `sql` DQ rules: the SQL query to be executed. Note that it should match the target SQL engine/database, no transalation service are provided here. | +|quality.engine |Third-party DQ Engine | No | Required for `custom` DQ rule: name of the third-party engine being used. Any value is authorized here but common values are `soda`, `gx`, `montecarlo`, etc. | +|quality.implementation |Third-party Implementation| No | A text (non-parsed) block of code required for the third-party DQ engine to run. | +|quality.dimension |Dimension | No | The key performance indicator (KPI) or dimension for data quality. Valid values are liste after the table. | +|quality.method |Method | No | Values are open and include `reconciliation`. | +|quality.severity |Severity | No | The severity of the DQ rule. | +|quality.businessImpact |Business Impact | No | Consequences of the rule failure. | +|quality.customProperties |Custom Properties | No | Additional properties required for rulee execution. Follows the same structure as any custom properties block. | +|quality.tags |Tags | No | Tags. Follows the same structure as any tags property. | +|quality.authoritativeDefinitions|Authoritative Definitions | No | Authoritative definitions indicate the link to external definition. Follows the same structure as any authoritative definitions block. | +|quality.scheduler |Scheduler | No | Name of the scheduler, can be `cron` or any tool your organization support. | +|quality.schedule |Scheduler Configuration | No | Configuration information for the scheduling tool, for `cron` a possible value is `0 20 * * *`. | + +#### Valid Values for Dimension +Those data quality dimensions are used for classification and reporting in data quality. Valid values are: * `Accuracy` (synonym `Ac`), * `Completeness` (synonym `Cp`), @@ -452,6 +456,23 @@ quality: * `Timeliness` (synonym `Tm`), * `Uniqueness` (synonym `Uq`). +#### Valid Properties for Operator +The operator specifies the condition to validate the rule. + +|Operator |Expected Value |Math Symbol |Example | +|-----------------------|-------------------|-------------|----------------------------| +|mustBe |number | `=` |`mustBe: 5` | +|mustNotBe |number | `<>`, `≠` |`mustNotBe: 3.14` | +|mustBeGreaterThan |number | `>` |`mustBeGreaterThan: 59` | +|mustBeGreaterOrEqualTo |number | `>=`, `≥` |`mustBeGreaterOrEqualTo: 60`| +|mustBeLessThan |number | `<` |`mustBeLessThan: 1000` | +|mustBeLessOrEqualTo |number | `<=`, `≤` |`mustBeLessOrEqualTo: 999` | +|mustBeBetween |list of two numbers| `⊂` |`mustBeBetween: [0, 100]` | +|mustNotBeBetween |list of two numbers| `⊄` |`mustNotBeBetween: [0, 100]`| + +#### Implicit Rules +Bitol has the ambition of creating a standard set of implicit data quality rules. Join the working group around [RFC #0012](https://github.com/bitol-io/tsc/blob/main/rfcs/0012-implicit-dq-rules.md). + ## Support & communication channels Support and communication channels help consumers find help regarding their use of the data contract. In version 3, ODCS opens the From a889efdeb07cb958ad41fb11412895d085cc4892 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 11 Sep 2024 11:36:37 -0400 Subject: [PATCH 35/93] Update README.md --- docs/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/README.md b/docs/README.md index feb4ab5..b584cf9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -470,6 +470,28 @@ The operator specifies the condition to validate the rule. |mustBeBetween |list of two numbers| `⊂` |`mustBeBetween: [0, 100]` | |mustNotBeBetween |list of two numbers| `⊄` |`mustNotBeBetween: [0, 100]`| +`mustBeBetween` is the equivalent to `mustBeGreaterThan` and `mustBeLessThan`. + +```yaml +quality: + - type: sql + query: | + SELECT COUNT(*) FROM ${table} WHERE ${column} IS NOT NULL + mustBeBetween: [0, 100] +``` + +is equivalent to: + +```yaml +quality: + - type: sql + query: | + SELECT COUNT(*) FROM ${table} WHERE ${column} IS NOT NULL + mustBeGreaterThan: 0 + mustBeLessThan: 100 +``` + + #### Implicit Rules Bitol has the ambition of creating a standard set of implicit data quality rules. Join the working group around [RFC #0012](https://github.com/bitol-io/tsc/blob/main/rfcs/0012-implicit-dq-rules.md). From 4ae966a85278c9e449c7219503a1679ce886f4cd Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 11 Sep 2024 11:39:54 -0400 Subject: [PATCH 36/93] Update README.md --- docs/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/README.md b/docs/README.md index b584cf9..f5e8aff 100644 --- a/docs/README.md +++ b/docs/README.md @@ -459,16 +459,16 @@ Those data quality dimensions are used for classification and reporting in data #### Valid Properties for Operator The operator specifies the condition to validate the rule. -|Operator |Expected Value |Math Symbol |Example | -|-----------------------|-------------------|-------------|----------------------------| -|mustBe |number | `=` |`mustBe: 5` | -|mustNotBe |number | `<>`, `≠` |`mustNotBe: 3.14` | -|mustBeGreaterThan |number | `>` |`mustBeGreaterThan: 59` | -|mustBeGreaterOrEqualTo |number | `>=`, `≥` |`mustBeGreaterOrEqualTo: 60`| -|mustBeLessThan |number | `<` |`mustBeLessThan: 1000` | -|mustBeLessOrEqualTo |number | `<=`, `≤` |`mustBeLessOrEqualTo: 999` | -|mustBeBetween |list of two numbers| `⊂` |`mustBeBetween: [0, 100]` | -|mustNotBeBetween |list of two numbers| `⊄` |`mustNotBeBetween: [0, 100]`| +|Operator |Expected Value |Math Symbol |Example | +|-------------------------|-------------------|-------------|----------------------------| +|`mustBe` |number | `=` |`mustBe: 5` | +|`mustNotBe` |number | `<>`, `≠` |`mustNotBe: 3.14` | +|`mustBeGreaterThan` |number | `>` |`mustBeGreaterThan: 59` | +|`mustBeGreaterOrEqualTo` |number | `>=`, `≥` |`mustBeGreaterOrEqualTo: 60`| +|`mustBeLessThan` |number | `<` |`mustBeLessThan: 1000` | +|`mustBeLessOrEqualTo` |number | `<=`, `≤` |`mustBeLessOrEqualTo: 999` | +|`mustBeBetween` |list of two numbers| `⊂` |`mustBeBetween: [0, 100]` | +|`mustNotBeBetween` |list of two numbers| `⊄` |`mustNotBeBetween: [0, 100]`| `mustBeBetween` is the equivalent to `mustBeGreaterThan` and `mustBeLessThan`. From 79ec2e2516b39d0766d1001c7b567cddd7260c58 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 11 Sep 2024 14:00:30 -0400 Subject: [PATCH 37/93] Update post Jochen's review --- CHANGELOG.md | 5 +++- docs/README.md | 68 +++++++++++++++++++++++++------------------------- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c2ce9e..fa7380e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,10 @@ This document tracks the history and evolution of the **Open Data Contract Stand * Restrict `dataset.table.columns.column.logicalType` to be one of `string`, `date`, `number`, `integer`, `object`, `array`, `boolean`. * Add `dataset.table.columns.column.logicalTypeOptions`. * **Changes** to Data Quality: - * TBD. + * Significant changes have been applied to support more tools and use cases. + * If needed, `templateName` is a custom property. + * `toolName` is obsolete, replaced by `type=custom; engine: `. + * `scheduleCronExpression` is replaced by `schedule` and `scheduler`. `scheduleCronExpression: 0 20 * * *` becomes `schedule: 0 20 * * *` and `scheduler: cron`. * Pricing: * No changes. * **Changes** to team (fka stakeholders): diff --git a/docs/README.md b/docs/README.md index f5e8aff..60e95eb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -363,13 +363,13 @@ quality: ``` ### SQL -A single SQL query that returns either a numeric or boolean value for comparison. The query must be written in the SQL dialect specific to the provided server. +A single SQL query that returns either a numeric or boolean value for comparison. The query must be written in the SQL dialect specific to the provided server. `${object}` and `${property}` are automatically replaced by the current object (in the case of SQL on a relational database, the table or view name) and the current property name (in the case of SQL on a relational database, the column). ```yaml quality: - type: sql query: | - SELECT COUNT(*) FROM ${table} WHERE ${column} IS NOT NULL + SELECT COUNT(*) FROM ${object} WHERE ${property} IS NOT NULL mustBeLessThan: 3600 ``` @@ -395,12 +395,12 @@ quality: ```yaml quality: - type: custom - engine: great-expectations + engine: greatExpectations implementation: | type: expect_table_row_count_to_be_between # Block kwargs: # passed as-is minValue: 10000 # to the tool - maxValue: 50000 # (GX in this situation) + maxValue: 50000 # (Great Expectations in this situation) ``` ### Scheduling @@ -410,7 +410,7 @@ The data contract can contain scheduling information for executing the rules. Yo quality: - type: sql query: | - SELECT COUNT(*) FROM ${table} WHERE ${column} IS NOT NULL + SELECT COUNT(*) FROM ${object} WHERE ${property} IS NOT NULL mustBeLessThan: 3600 scheduler: cron schedule: 0 20 * * * @@ -422,39 +422,39 @@ quality: Acronyms: * DQ: data quality. -|Key |UX label |Required| Description | -|--------------------------------|--------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | -|quality.name |Name | No | A short name for the rule. | -|quality.description |Description | No | Describe the quality check to be completed. | -|quality.type |Type | No | Type of DQ rule. Valid values are `implicit` (default), `text`, `sql`, and `custom`. | -|quality.rule |Rule name | No | Required for `implicit` DQ rules: the name of the rule to be executed. | -|quality.\ |See below | No | Multiple values are allowed for the **property**, the value is the one to compare to. | -|quality.unit |Unit | No | Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed. | -|quality.validValues |Valid values | No | Static list of valid values. | -|quality.query |SQL Query | No | Required for `sql` DQ rules: the SQL query to be executed. Note that it should match the target SQL engine/database, no transalation service are provided here. | -|quality.engine |Third-party DQ Engine | No | Required for `custom` DQ rule: name of the third-party engine being used. Any value is authorized here but common values are `soda`, `gx`, `montecarlo`, etc. | -|quality.implementation |Third-party Implementation| No | A text (non-parsed) block of code required for the third-party DQ engine to run. | -|quality.dimension |Dimension | No | The key performance indicator (KPI) or dimension for data quality. Valid values are liste after the table. | -|quality.method |Method | No | Values are open and include `reconciliation`. | -|quality.severity |Severity | No | The severity of the DQ rule. | -|quality.businessImpact |Business Impact | No | Consequences of the rule failure. | -|quality.customProperties |Custom Properties | No | Additional properties required for rulee execution. Follows the same structure as any custom properties block. | -|quality.tags |Tags | No | Tags. Follows the same structure as any tags property. | -|quality.authoritativeDefinitions|Authoritative Definitions | No | Authoritative definitions indicate the link to external definition. Follows the same structure as any authoritative definitions block. | -|quality.scheduler |Scheduler | No | Name of the scheduler, can be `cron` or any tool your organization support. | -|quality.schedule |Scheduler Configuration | No | Configuration information for the scheduling tool, for `cron` a possible value is `0 20 * * *`. | +|Key |UX label |Required| Description | +|--------------------------------|--------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | +|quality.name |Name | No | A short name for the rule. | +|quality.description |Description | No | Describe the quality check to be completed. | +|quality.type |Type | No | Type of DQ rule. Valid values are `implicit` (default), `text`, `sql`, and `custom`. | +|quality.rule |Rule name | No | Required for `implicit` DQ rules: the name of the rule to be executed. | +|quality.\ |See below | No | Multiple values are allowed for the **property**, the value is the one to compare to. | +|quality.unit |Unit | No | Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed. | +|quality.validValues |Valid values | No | Static list of valid values. | +|quality.query |SQL Query | No | Required for `sql` DQ rules: the SQL query to be executed. Note that it should match the target SQL engine/database, no transalation service are provided here. | +|quality.engine |Third-party DQ Engine | No | Required for `custom` DQ rule: name of the third-party engine being used. Any value is authorized here but common values are `soda`, `greatExpectations`, `montecarlo`, etc. | +|quality.implementation |Third-party Implementation| No | A text (non-parsed) block of code required for the third-party DQ engine to run. | +|quality.dimension |Dimension | No | The key performance indicator (KPI) or dimension for data quality. Valid values are listed after the table. | +|quality.method |Method | No | Values are open and include `reconciliation`. | +|quality.severity |Severity | No | The severity of the DQ rule. | +|quality.businessImpact |Business Impact | No | Consequences of the rule failure. | +|quality.customProperties |Custom Properties | No | Additional properties required for rulee execution. Follows the same structure as any custom properties block. | +|quality.tags |Tags | No | Tags. Follows the same structure as any tags property. | +|quality.authoritativeDefinitions|Authoritative Definitions | No | Authoritative definitions indicate the link to external definition. Follows the same structure as any authoritative definitions block. | +|quality.scheduler |Scheduler | No | Name of the scheduler, can be `cron` or any tool your organization support. | +|quality.schedule |Scheduler Configuration | No | Configuration information for the scheduling tool, for `cron` a possible value is `0 20 * * *`. | #### Valid Values for Dimension Those data quality dimensions are used for classification and reporting in data quality. Valid values are: - * `Accuracy` (synonym `Ac`), - * `Completeness` (synonym `Cp`), - * `Conformity` (synonym `Cf`), - * `Consistency` (synonym `Cs`), - * `Coverage` (synonym `Cv`), - * `Timeliness` (synonym `Tm`), - * `Uniqueness` (synonym `Uq`). + * `accuracy` (synonym `ac`), + * `completeness` (synonym `cp`), + * `conformity` (synonym `cf`), + * `consistency` (synonym `cs`), + * `coverage` (synonym `cv`), + * `timeliness` (synonym `tm`), + * `uniqueness` (synonym `uq`). #### Valid Properties for Operator The operator specifies the condition to validate the rule. From ff172917d7caf154c4351d342c642861f56d7f9e Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 11 Sep 2024 14:02:09 -0400 Subject: [PATCH 38/93] Update CHANGELOG.md Signed-off-by: Jean-Georges Perrin --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa7380e..bae7f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,7 @@ This document tracks the history and evolution of the **Open Data Contract Stand * Restrict `dataset.table.columns.column.logicalType` to be one of `string`, `date`, `number`, `integer`, `object`, `array`, `boolean`. * Add `dataset.table.columns.column.logicalTypeOptions`. * **Changes** to Data Quality: - * Significant changes have been applied to support more tools and use cases. + * Significant changes have been applied to support more tools and use cases. Please review the new section. * If needed, `templateName` is a custom property. * `toolName` is obsolete, replaced by `type=custom; engine: `. * `scheduleCronExpression` is replaced by `schedule` and `scheduler`. `scheduleCronExpression: 0 20 * * *` becomes `schedule: 0 20 * * *` and `scheduler: cron`. From 756c5339504372330e3f33d76e73de35cf492621 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 11 Sep 2024 14:50:17 -0400 Subject: [PATCH 39/93] Update CONTRIBUTING.md --- CONTRIBUTING.md | 83 +------------------------------------------------ 1 file changed, 1 insertion(+), 82 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 022d4c2..6d48ae3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,86 +6,5 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color # Open Data Contract Standard -## Executive summary -First off, thanks for taking the time to contribute! ❤️ +Please refer to the [TSC contributing guidelines](https://github.com/bitol-io/tsc/blob/main/CONTRIBUTING.md). -All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉 - -You do not have to be a member of AIDA User Group to contribute, although becoming a member is free. Strength is always in the number. Check [it out](https://aidausergroup.org/join/). - -> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: -> - Star the project. -> - Tweet about it. -> - Refer this project in your project's readme. -> - Mention the project at local meetups and tell your friends/colleagues. - - -## Table of Contents - -- [Code of Conduct](#code-of-conduct) -- [I Have a Question](#i-have-a-question) -- [I Want To Contribute](#i-want-to-contribute) -- [Suggesting Enhancements](#suggesting-enhancements) -- [Improving The Documentation](#improving-the-documentation) -- [Join The Project Team](#join-the-project-team) - - -## Code of Conduct - -This project and everyone participating in it is governed by the -[Open Data Contract Standard Code of Conduct](blob/master/CODE_OF_CONDUCT.md). -By participating, you are expected to uphold this code. Please report unacceptable behavior -to [@jgperrin](https://github.com/jgperrin). - - -## I Have a Question - -** New ** - -AIDA User Group also opened its Slack for Data Contract discussion. It is an alternate way of contributing to this project. The Slack channel is now [available](https://aidaug.slack.com/archives/C05UZRSBKLY). - -You have to be a member of AIDA User Group (it's free) to have access to our Slack channel. All the details are [here](https://aidausergroup.org/welcome/). - -> If you want to ask a question, we assume that you have read the available [Documentation](https://github.com/AIDAUserGroup/open-data-contract-standard). - -Before you ask a question, it is best to search for existing [Issues](https://github.com/bitol-io/open-data-contract-standard/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. - -If you then still feel the need to ask a question and need clarification, we recommend the following: - -- Open a [New Issue](https://github.com/bitol-io/open-data-contract-standard/issues/new). -- Provide as much context as you can about what you're running into. - -We will then take care of the issue as soon as possible. - -## I Want To Contribute - -> ### Legal Notice -> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license. - -### Suggesting Enhancements - -This section guides you through submitting an enhancement suggestion for Data Contract Template, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. - - -#### Before Submitting an Enhancement - -- Make sure that you are using the latest version. -- Read the [documentation](https://github.com/AIDAUserGroup/open-data-contract-standard) carefully and find out if the functionality is already covered. -- Perform a [search](https://github.com/bitol-io/open-data-contract-standard/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. -- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. - - -#### How Do I Submit a Good Enhancement Suggestion? - -Enhancement suggestions are tracked as [GitHub issues](https://github.com/bitol-io/open-data-contract-standard/issues). - -- Use a **clear and descriptive title** for the issue to identify the suggestion. -- Provide a **step-by-step description of the suggested enhancement** in as many details as possible. -- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. -- **Explain why this enhancement would be useful** to most Open Data Contract Standard users. You may also want to point out the other projects that solved it better and which could serve as inspiration. - -### Improving The Documentation -Please contact [@jgperrin](https://github.com/jgperrin). Examples are always welcome. - -## Join The Project Team -Please contact [@jgperrin](https://github.com/jgperrin). From ddf6368e910e2cf50ef8623a3a63506ca5016f9c Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 11 Sep 2024 14:51:07 -0400 Subject: [PATCH 40/93] Update CONTRIBUTING.md --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d48ae3..10c36c4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ description: "How you can contribute to the Open Data Contract Standard (ODCS)." image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color/Bitol_Logo_color.svg" --- -# Open Data Contract Standard +# Contributing to Open Data Contract Standard -Please refer to the [TSC contributing guidelines](https://github.com/bitol-io/tsc/blob/main/CONTRIBUTING.md). +Thank you for your interest in contributing to Open Data Contract Standard (ODCS). Please refer to the [TSC contributing guidelines](https://github.com/bitol-io/tsc/blob/main/CONTRIBUTING.md). From ec03e0a6195d8c7fcd9ef5847940811bf9296424 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 11 Sep 2024 14:53:23 -0400 Subject: [PATCH 41/93] Update README.md From a1f1e4182ea781c33f414f7ef320d8dc194e3cde Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Mon, 16 Sep 2024 14:41:26 +0200 Subject: [PATCH 42/93] First draft of describing the servers --- docs/README.md | 251 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 250 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 60e95eb..ce43742 100644 --- a/docs/README.md +++ b/docs/README.md @@ -698,7 +698,256 @@ slaProperties: | slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | ## Infrastructure & servers -TBD + + +This section describes the different types of servers available in the Open Data Contract Standard (ODCS) JSON Schema. Each server type is documented with specific field descriptions and an example in YAML. + +### General Server Structure + +Each server in the schema has the following structure: + +```yaml +servers: + - type: + description: + environment: + roles: + - + customProperties: + - +``` + +#### Common Server Properties + +- **type**: The type of server. Valid values include various server technologies like `athena`, `bigquery`, `postgres`, etc. +- **description**: A description of the server. +- **environment**: The environment where the server operates (e.g., `prod`, `dev`, `uat`). +- **roles**: An array of roles that have access to the server. +- **customProperties**: Any additional custom properties specific to the server. + +--- + +### Athena + +#### Fields specific to Athena: +- **stagingDir**: The Amazon S3 path where Amazon Athena stores query results and metadata. +- **schema**: The schema within the data source. +- **catalog**: The catalog name for the Athena server (defaults to `awsdatacatalog`). +- **regionName**: The AWS region for the Athena service. + +#### YAML Example: + +```yaml +servers: + - type: athena + description: Amazon Athena server for querying S3 data + environment: prod + stagingDir: s3://my_storage_account_name/my_container/path + schema: my_schema + catalog: awsdatacatalog + regionName: eu-west-1 +``` + +--- + +### Azure + +#### Fields specific to Azure: +- **location**: The Azure Blob Storage or Data Lake Storage URI. +- **format**: The file format stored in Azure (`parquet`, `delta`, `json`, `csv`). +- **delimiter**: For JSON format only, defines how multiple JSON documents are delimited (`new_line`, `array`). + +#### YAML Example: + +```yaml +servers: + - type: azure + description: Azure Blob Storage or Data Lake Storage + environment: preprod + location: az://my_storage_account_name.blob.core.windows.net/my_container/path/*.parquet + format: parquet + delimiter: new_line +``` + +--- + +### BigQuery + +#### Fields specific to BigQuery: +- **project**: The GCP project name. +- **dataset**: The BigQuery dataset name. + +#### YAML Example: + +```yaml +servers: + - type: bigquery + description: Google BigQuery server + environment: prod + project: my_project + dataset: my_dataset +``` + +--- + +### ClickHouse + +#### Fields specific to ClickHouse: +- **host**: The hostname or IP address of the ClickHouse server. +- **port**: The port number of the ClickHouse server. +- **database**: The name of the database. + +#### YAML Example: + +```yaml +servers: + - type: clickhouse + description: ClickHouse server for analytics + environment: dev + host: clickhouse.example.com + port: 8123 + database: my_database +``` + +--- + +### Databricks + +#### Fields specific to Databricks: +- **host**: The Databricks server hostname. +- **catalog**: The name of the catalog (either Hive or Unity). +- **schema**: The schema within the catalog. + +#### YAML Example: + +```yaml +servers: + - type: databricks + description: Databricks server for analytics + environment: prod + host: dbc-abcdefgh-1234.cloud.databricks.com + catalog: my_catalog + schema: my_schema +``` + +--- + +### Denodo + +#### Fields specific to Denodo: +- **host**: The hostname or IP address of the Denodo server. +- **port**: The port number of the Denodo server. +- **database**: The name of the database. + +#### YAML Example: + +```yaml +servers: + - type: denodo + description: Denodo server for data virtualization + environment: dev + host: denodo.example.com + port: 9999 + database: my_database +``` + +--- + +### PostgreSQL + +#### Fields specific to PostgreSQL: +- **host**: The hostname or IP address of the PostgreSQL server. +- **port**: The port number of the PostgreSQL server. +- **database**: The name of the database. +- **schema**: The schema within the PostgreSQL database. + +#### YAML Example: + +```yaml +servers: + - type: postgres + description: PostgreSQL database server + environment: prod + host: postgres.example.com + port: 5432 + database: my_database + schema: public +``` + +--- + +### Snowflake + +#### Fields specific to Snowflake: +- **host**: The hostname of the Snowflake server. +- **port**: The port number of the Snowflake server. +- **account**: The Snowflake account name. +- **database**: The database name. +- **warehouse**: The name of the Snowflake virtual warehouse. +- **schema**: The schema within the Snowflake database. + +#### YAML Example: + +```yaml +servers: + - type: snowflake + description: Snowflake data warehouse + environment: prod + host: snowflake.example.com + port: 443 + account: my_account + database: my_database + warehouse: my_warehouse + schema: public +``` + +--- + +### S3 + +#### Fields specific to S3: +- **location**: The S3 URL where data is stored (must start with `s3://`). +- **format**: The file format (`parquet`, `json`, `csv`, etc.). +- **delimiter**: For JSON format only, defines how multiple JSON documents are delimited (`new_line`, `array`). + +#### YAML Example: + +```yaml +servers: + - type: s3 + description: Amazon S3 storage server + environment: uat + location: s3://datacontract-example-orders-latest/data/*.json + format: json + delimiter: new_line +``` + +--- + +### Kafka + +#### Fields specific to Kafka: +- **host**: The bootstrap server URL of the Kafka cluster. +- **topic**: The topic name in the Kafka server. +- **format**: The message format in Kafka (`json`, `avro`, `protobuf`, `xml`). + +#### YAML Example: + +```yaml +servers: + - type: kafka + description: Apache Kafka server + environment: prod + host: kafka.example.com + topic: my_topic + format: json +``` + +--- + +Each server type can be customized with different properties such as `host`, `port`, `database`, and `schema`, depending on the server technology in use. Refer to the specific documentation for each server type for additional configurations. + + ## Custom Properties This section covers custom properties you may find in a data contract. From d15886482ce6164906aafc030e502e4e5d4fbc3f Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Mon, 16 Sep 2024 18:11:00 +0200 Subject: [PATCH 43/93] Add docs for server types --- docs/README.md | 443 ++++++++++++++++------------ schema/odcs-json-schema-v3.0.0.json | 4 +- script/generate-server-types.ruby | 60 ++++ 3 files changed, 314 insertions(+), 193 deletions(-) create mode 100644 script/generate-server-types.ruby diff --git a/docs/README.md b/docs/README.md index ce43742..dd2b3bf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -699,8 +699,15 @@ slaProperties: ## Infrastructure & servers +The `servers` element describes where the data protected by this data contract is *physically* located. That metadata helps to know where the data is so that a data consumer can discover the data and a platform engineer can automate access. -This section describes the different types of servers available in the Open Data Contract Standard (ODCS) JSON Schema. Each server type is documented with specific field descriptions and an example in YAML. +A `server` describes a single dataset on a specific environment and a specific technology. The `servers` element can contain multiple servers, each with its own configuration. + +The typical ways of using the top level `servers` element are as follows: +- **Single Server:** The data contract protects a specific dataset at a specific location. *Example:* a CSV file on an SFTP server. +- **Multiple Environments:** The data contract makes sure that the data is protected in all environments. *Example:* a data product with data in a dev, uat, and prod environment on Databricks. +- **Different Technologies:** The data contract makes sure that regardless of the offered technology, it still holds. *Example:* a data product offers its data in a kafka topic and in a BigQuery table that should have the same structure and content. +- **Different Technologies and Multiple Environments:** The data contract makes sure that regardless of the offered technology and environment, it still holds. *Example:* a data product offers its data in a kafka topic and in a BigQuery table that should have the same structure and content in dev, uat, and prod. ### General Server Structure @@ -711,6 +718,7 @@ servers: - type: description: environment: + # according to the server type roles: - customProperties: @@ -725,227 +733,280 @@ servers: - **roles**: An array of roles that have access to the server. - **customProperties**: Any additional custom properties specific to the server. ---- - -### Athena - -#### Fields specific to Athena: -- **stagingDir**: The Amazon S3 path where Amazon Athena stores query results and metadata. -- **schema**: The schema within the data source. -- **catalog**: The catalog name for the Athena server (defaults to `awsdatacatalog`). -- **regionName**: The AWS region for the Athena service. - -#### YAML Example: - -```yaml -servers: - - type: athena - description: Amazon Athena server for querying S3 data - environment: prod - stagingDir: s3://my_storage_account_name/my_container/path - schema: my_schema - catalog: awsdatacatalog - regionName: eu-west-1 -``` - ---- - -### Azure - -#### Fields specific to Azure: -- **location**: The Azure Blob Storage or Data Lake Storage URI. -- **format**: The file format stored in Azure (`parquet`, `delta`, `json`, `csv`). -- **delimiter**: For JSON format only, defines how multiple JSON documents are delimited (`new_line`, `array`). - -#### YAML Example: - -```yaml -servers: - - type: azure - description: Azure Blob Storage or Data Lake Storage - environment: preprod - location: az://my_storage_account_name.blob.core.windows.net/my_container/path/*.parquet - format: parquet - delimiter: new_line -``` - ---- - -### BigQuery - -#### Fields specific to BigQuery: -- **project**: The GCP project name. -- **dataset**: The BigQuery dataset name. - -#### YAML Example: - -```yaml -servers: - - type: bigquery - description: Google BigQuery server - environment: prod - project: my_project - dataset: my_dataset -``` - ---- - -### ClickHouse +### Specific Server Properties -#### Fields specific to ClickHouse: -- **host**: The hostname or IP address of the ClickHouse server. -- **port**: The port number of the ClickHouse server. -- **database**: The name of the database. - -#### YAML Example: +Each server type can be customized with different properties such as `host`, `port`, `database`, and `schema`, depending on the server technology in use. Refer to the specific documentation for each server type for additional configurations. -```yaml -servers: - - type: clickhouse - description: ClickHouse server for analytics - environment: dev - host: clickhouse.example.com - port: 8123 - database: my_database -``` +#### Server Types + +- [athena](#athena-server) +- [azure](#azure-server) +- [bigquery](#bigquery-server) +- [clickhouse](#clickhouse-server) +- [databricks](#databricks-server) +- [denodo](#denodo-server) +- [dremio](#dremio-server) +- [duckdb](#duckdb-server) +- [glue](#glue-server) +- [googlecloudsql](#googlecloudsql-server) +- [ibmdb2](#ibmdb2-server) +- [kafka](#kafka-server) +- [kinesis](#kinesis-server) +- [local](#local-server) +- [mysql](#mysql-server) +- [oracle](#oracle-server) +- [postgres](#postgres-server) +- [presto](#presto-server) +- [pubsub](#pubsub-server) +- [redshift](#redshift-server) +- [s3](#s3-server) +- [sftp](#sftp-server) +- [snowflake](#snowflake-server) +- [sqlserver](#sqlserver-server) +- [synapse](#synapse-server) +- [trino](#trino-server) +- [vertica](#vertica-server) --- -### Databricks - -#### Fields specific to Databricks: -- **host**: The Databricks server hostname. -- **catalog**: The name of the catalog (either Hive or Unity). -- **schema**: The schema within the catalog. - -#### YAML Example: - -```yaml -servers: - - type: databricks - description: Databricks server for analytics - environment: prod - host: dbc-abcdefgh-1234.cloud.databricks.com - catalog: my_catalog - schema: my_schema -``` - ---- -### Denodo +## Athena Server -#### Fields specific to Denodo: -- **host**: The hostname or IP address of the Denodo server. -- **port**: The port number of the Denodo server. -- **database**: The name of the database. +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **schema** | Schema | Yes | Identify the schema in the data source in which your tables exist. | +| **stagingDir** | Stagingdir | No | Amazon Athena automatically stores query results and metadata information for each query that runs in a query result location that you can specify in Amazon S3. | +| **catalog** | Catalog | No | Identify the name of the Data Source, also referred to as a Catalog. | +| **regionName** | Regionname | No | The region your AWS account uses. | -#### YAML Example: +## Azure Server -```yaml -servers: - - type: denodo - description: Denodo server for data virtualization - environment: dev - host: denodo.example.com - port: 9999 - database: my_database -``` +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **location** | Location | Yes | Fully qualified path to Azure Blob Storage or Azure Data Lake Storage (ADLS), supports globs. | +| **format** | Format | Yes | File format. | +| **delimiter** | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | ---- +## Bigquery Server -### PostgreSQL +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **project** | Project | Yes | The GCP project name. | +| **dataset** | Dataset | Yes | The GCP dataset name. | -#### Fields specific to PostgreSQL: -- **host**: The hostname or IP address of the PostgreSQL server. -- **port**: The port number of the PostgreSQL server. -- **database**: The name of the database. -- **schema**: The schema within the PostgreSQL database. +## Clickhouse Server -#### YAML Example: +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the ClickHouse server. | +| **port** | Port | Yes | The port to the ClickHouse server. | +| **database** | Database | Yes | The name of the database. | -```yaml -servers: - - type: postgres - description: PostgreSQL database server - environment: prod - host: postgres.example.com - port: 5432 - database: my_database - schema: public -``` +## Databricks Server ---- +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **catalog** | Catalog | Yes | The name of the Hive or Unity catalog | +| **schema** | Schema | Yes | The schema name in the catalog | +| **host** | Host | No | The Databricks host | -### Snowflake +## Denodo Server -#### Fields specific to Snowflake: -- **host**: The hostname of the Snowflake server. -- **port**: The port number of the Snowflake server. -- **account**: The Snowflake account name. -- **database**: The database name. -- **warehouse**: The name of the Snowflake virtual warehouse. -- **schema**: The schema within the Snowflake database. +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the Denodo server. | +| **port** | Port | Yes | The port of the Denodo server. | +| **database** | Database | No | The name of the database. | -#### YAML Example: +## Dremio Server -```yaml -servers: - - type: snowflake - description: Snowflake data warehouse - environment: prod - host: snowflake.example.com - port: 443 - account: my_account - database: my_database - warehouse: my_warehouse - schema: public -``` +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the Dremio server. | +| **port** | Port | Yes | The port of the Dremio server. | +| **schema** | Schema | No | The name of the schema. | ---- +## Duckdb Server -### S3 +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **database** | Database | Yes | Path to duckdb database file. | +| **schema** | Schema | No | The name of the schema. | -#### Fields specific to S3: -- **location**: The S3 URL where data is stored (must start with `s3://`). -- **format**: The file format (`parquet`, `json`, `csv`, etc.). -- **delimiter**: For JSON format only, defines how multiple JSON documents are delimited (`new_line`, `array`). +## Glue Server -#### YAML Example: +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **account** | Account | Yes | The AWS Glue account | +| **database** | Database | Yes | The AWS Glue database name | +| **location** | Location | No | The AWS S3 path. Must be in the form of a URL. | +| **format** | Format | No | The format of the files | -```yaml -servers: - - type: s3 - description: Amazon S3 storage server - environment: uat - location: s3://datacontract-example-orders-latest/data/*.json - format: json - delimiter: new_line -``` +## Googlecloudsql Server ---- +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the Google Cloud Sql server. | +| **port** | Port | Yes | The port of the Google Cloud Sql server. | +| **database** | Database | Yes | The name of the database. | +| **schema** | Schema | Yes | The name of the schema. | -### Kafka +## Ibmdb2 Server -#### Fields specific to Kafka: -- **host**: The bootstrap server URL of the Kafka cluster. -- **topic**: The topic name in the Kafka server. -- **format**: The message format in Kafka (`json`, `avro`, `protobuf`, `xml`). +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the IBM DB2 server. | +| **port** | Port | Yes | The port of the IBM DB2 server. | +| **database** | Database | Yes | The name of the database. | +| **schema** | Schema | No | The name of the schema. | -#### YAML Example: +## Kafka Server -```yaml -servers: - - type: kafka - description: Apache Kafka server - environment: prod - host: kafka.example.com - topic: my_topic - format: json -``` +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The bootstrap server of the kafka cluster. | +| **topic** | Topic | Yes | The topic name. | +| **format** | Format | No | The format of the messages. | + +## Kinesis Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **stream** | Stream | Yes | The name of the Kinesis data stream. | +| **region** | Region | No | AWS region. | +| **format** | Format | No | The format of the record | + +## Local Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **path** | Path | Yes | The relative or absolute path to the data file(s). | +| **format** | Format | Yes | The format of the file(s) | + +## Mssql Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the MS Sql server. | +| **port** | Port | Yes | The port of the MS Sql server. | +| **database** | Database | Yes | The name of the database. | +| **schema** | Schema | Yes | The name of the schema. | +| **driver** | Driver | No | Version of ODBC driver to use. | + +## Mysql Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the MySql server. | +| **port** | Port | Yes | The port of the MySql server. | +| **database** | Database | Yes | The name of the database. | + +## Oracle Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host to the oracle server | +| **port** | Port | Yes | The port to the oracle server. | +| **serviceName** | Servicename | Yes | The name of the service. | + +## Postgres Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host to the Postgres server | +| **port** | Port | Yes | The port to the Postgres server. | +| **database** | Database | Yes | The name of the database. | +| **schema** | Schema | Yes | The name of the schema in the database. | + +## Presto Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host to the Presto server | +| **catalog** | Catalog | No | The name of the catalog. | +| **schema** | Schema | No | The name of the schema. | + +## Pubsub Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **project** | Project | Yes | The GCP project name. | +| **topic** | Topic | Yes | The topic name. | + +## Redshift Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | An optional string describing the server. | +| **database** | Database | Yes | The name of the database. | +| **schema** | Schema | Yes | The name of the schema. | +| **region** | Region | No | AWS region of Redshift server. | +| **account** | Account | No | The account used by the server. | + +## S3 Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **location** | Location | Yes | S3 URL, starting with `s3://` | +| **endpointUrl** | Endpointurl | No | The server endpoint for S3-compatible servers. | +| **format** | Format | No | File format. | +| **delimiter** | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | + +## Sftp Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **location** | Location | Yes | SFTP URL, starting with `sftp://` | +| **format** | Format | No | File format. | +| **delimiter** | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | + +## Snowflake Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host to the Snowflake server | +| **port** | Port | Yes | The port to the Snowflake server. | +| **account** | Account | Yes | The Snowflake account used by the server. | +| **database** | Database | Yes | The name of the database. | +| **warehouse** | Warehouse | Yes | The name of the cluster of resources that is a Snowflake virtual warehouse. | +| **schema** | Schema | Yes | The name of the schema. | + +## Sqlserver Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host to the database server | +| **database** | Database | Yes | The name of the database. | +| **schema** | Schema | Yes | The name of the schema in the database. | +| **port** | Port | No | The port to the database server. | + +## Synapse Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the Synapse server. | +| **port** | Port | Yes | The port of the Synapse server. | +| **database** | Database | Yes | The name of the database. | + +## Trino Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The Trino host URL. | +| **port** | Port | Yes | The Trino port. | +| **catalog** | Catalog | Yes | The name of the catalog. | +| **schema** | Schema | Yes | The name of the schema in the database. | + +## Vertica Server + +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| **host** | Host | Yes | The host of the Vertica server. | +| **port** | Port | Yes | The port of the Vertica server. | +| **database** | Database | Yes | The name of the database. | +| **schema** | Schema | Yes | The name of the schema. | ---- -Each server type can be customized with different properties such as `host`, `port`, `database`, and `schema`, depending on the server technology in use. Refer to the specific documentation for each server type for additional configurations. diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 1d0c822..f1894ab 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -141,7 +141,7 @@ "description": "Type of the server.", "enum": [ "athena", "azure", "bigquery", "clickhouse", "databricks", "denodo", "dremio", - "duckdb", "glue", "googlecloudsql", "ibmdb2", "kafka", "kinesis", "local", "mssql", + "duckdb", "glue", "googlecloudsql", "ibmdb2", "kafka", "kinesis", "local", "mysql", "oracle", "postgres", "presto", "pubsub", "redshift", "s3", "sftp", "snowflake", "sqlserver", "synapse", "trino", "vertica" ] @@ -2192,4 +2192,4 @@ ] } } -} \ No newline at end of file +} diff --git a/script/generate-server-types.ruby b/script/generate-server-types.ruby new file mode 100644 index 0000000..1fe2a42 --- /dev/null +++ b/script/generate-server-types.ruby @@ -0,0 +1,60 @@ +require 'json' + +# Read the JSON schema file +file_path = 'schema/odcs-json-schema-v3.0.0.json' +schema = JSON.parse(File.read(file_path)) + +# Output file for Markdown documentation +output_file = 'server_types_tables.md' + +# Extract server types from the JSON Schema +server_definitions = schema['$defs']['Server']['allOf'] + +# Open the output file for writing +File.open(output_file, 'w') do |file| + # Iterate through each server type in the JSON schema + server_definitions.each do |definition| + puts definition + next unless definition['if'] && definition['then'] + + # Extract server type and details + server_type = definition['if']['properties']['type']['const'] + server_source_name = definition['then']['$ref'].split('/').last + puts server_type + server_details = schema['$defs']['ServerSource'][server_source_name] + required_fields = server_details['required'] || [] + puts required_fields + + # Write server type heading + file.puts "## #{server_type.capitalize} Server\n\n" + + # Write table header + file.puts "| Key | UX Label | Required | Description |\n" + file.puts "|--------------|-----------------|------------|------------------------------------------------------------|\n" + + puts "Before required fields" + + # First, print required fields + required_fields.each do |key| + if server_details['properties'].key?(key) + ux_label = key.split('_').map(&:capitalize).join(' ') # Generate UX label from the key + description = server_details['properties'][key]['description'] || "" + file.puts "| **#{key}** | #{ux_label} | Yes | #{description} |\n" + end + end + + puts "Required Fields" + + # Then, print the non-required fields + server_details['properties'].each do |key, value| + next if required_fields.include?(key) # Skip required fields as they are already printed + ux_label = key.split('_').map(&:capitalize).join(' ') # Generate UX label from the key + description = value['description'] || "" + file.puts "| **#{key}** | #{ux_label} | No | #{description} |\n" + end + + file.puts "\n" + end +end + +puts "Markdown tables generated in #{output_file}" From ff3c97bdbaac2815f970f5e4435311dfccceb267 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 17 Sep 2024 09:11:30 +0200 Subject: [PATCH 44/93] Quality: Rename type implicit to default --- docs/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index dd2b3bf..d9b67b7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -299,12 +299,12 @@ This section describes data quality rules & parameters. They are tightly linked Data quality rules support different levels/stages of data quality attributes: - __Text__: A human-readable text that describes the quality of the data. - - __Implicit__ rules: A maintained library of commonly-used predefined quality attributes such as `rowCount`, `unique`, `freshness`, and more. + - __Default__ rules: A maintained library of commonly-used predefined quality attributes such as `rowCount`, `unique`, `freshness`, and more. - __SQL__: An individual SQL query that returns a value that can be compared. Can be extended to `Python` or other. - __Custom__: Quality attributes that are vendor-specific, such as Soda, Great Expectations, dbt tests, or Montecarlo monitors. ### Text -A human-readable text that describes the quality of the data. Later in the development process, these might be translated into an executable check (such as `sql`), an implicit rule, or checked through an AI engine. +A human-readable text that describes the quality of the data. Later in the development process, these might be translated into an executable check (such as `sql`), a default rule, or checked through an AI engine. ```yaml quality: @@ -312,8 +312,8 @@ quality: description: The email address was verified by the system. ``` -### Implicit data quality rules -ODCS will provide a set of predefined (or implicit) rules commonly used in data quality checks, designed to be compatible with all major data quality engines. This simplifies the work for data engineers by eliminating the need to manually write SQL queries. +### Default data quality rules +ODCS will provide a set of predefined rules commonly used in data quality checks, designed to be compatible with all major data quality engines. This simplifies the work for data engineers by eliminating the need to manually write SQL queries. #### Property-level Those examples apply at the property level, such as column, field, etc. @@ -323,7 +323,7 @@ No more than 10 duplicate names. ```yaml quality: -- type: implicit # optional and default value for data quality rules +- type: default # optional and default value for data quality rules rule: duplicateCount mustBeLessThan: 10 name: Fewer than 10 duplicate names @@ -427,8 +427,8 @@ Acronyms: |quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | |quality.name |Name | No | A short name for the rule. | |quality.description |Description | No | Describe the quality check to be completed. | -|quality.type |Type | No | Type of DQ rule. Valid values are `implicit` (default), `text`, `sql`, and `custom`. | -|quality.rule |Rule name | No | Required for `implicit` DQ rules: the name of the rule to be executed. | +|quality.type |Type | No | Type of DQ rule. Valid values are `default` (default), `text`, `sql`, and `custom`. | +|quality.rule |Rule name | No | Required for `default` DQ rules: the name of the rule to be executed. | |quality.\ |See below | No | Multiple values are allowed for the **property**, the value is the one to compare to. | |quality.unit |Unit | No | Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed. | |quality.validValues |Valid values | No | Static list of valid values. | @@ -492,8 +492,8 @@ quality: ``` -#### Implicit Rules -Bitol has the ambition of creating a standard set of implicit data quality rules. Join the working group around [RFC #0012](https://github.com/bitol-io/tsc/blob/main/rfcs/0012-implicit-dq-rules.md). +#### Default Rules +Bitol has the ambition of creating a standard set of default data quality rules. Join the working group around [RFC #0012](https://github.com/bitol-io/tsc/blob/main/rfcs/0012-implicit-dq-rules.md). ## Support & communication channels From ce6a78f708798ef2aea743b8393e27e247c9f384 Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Tue, 17 Sep 2024 11:58:57 +0200 Subject: [PATCH 45/93] Remove server type mssql in favor of sqlserver (removed duplicate) --- docs/README.md | 10 ------ schema/odcs-json-schema-v3.0.0.json | 48 ----------------------------- 2 files changed, 58 deletions(-) diff --git a/docs/README.md b/docs/README.md index dd2b3bf..26bf3f5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -883,16 +883,6 @@ Each server type can be customized with different properties such as `host`, `po | **path** | Path | Yes | The relative or absolute path to the data file(s). | | **format** | Format | Yes | The format of the file(s) | -## Mssql Server - -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the MS Sql server. | -| **port** | Port | Yes | The port of the MS Sql server. | -| **database** | Database | Yes | The name of the database. | -| **schema** | Schema | Yes | The name of the schema. | -| **driver** | Driver | No | Version of ODBC driver to use. | - ## Mysql Server | Key | UX Label | Required | Description | diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index f1894ab..13652de 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -349,19 +349,6 @@ "$ref": "#/$defs/ServerSource/LocalServer" } }, - { - "if": { - "properties": { - "type": { - "const": "mssql" - } - }, - "required": ["type"] - }, - "then": { - "$ref": "#/$defs/ServerSource/MSSqlServer" - } - }, { "if": { "properties": { @@ -911,38 +898,6 @@ "format" ] }, - "MSSqlServer": { - "type": "object", - "title": "MSSqlServer", - "properties": { - "host": { - "type": "string", - "description": "The host of the MS Sql server." - }, - "port": { - "type": "integer", - "description": "The port of the MS Sql server." - }, - "database": { - "type": "string", - "description": "The name of the database." - }, - "schema": { - "type": "string", - "description": "The name of the schema." - }, - "driver": { - "type": "string", - "description": "Version of ODBC driver to use." - } - }, - "required": [ - "host", - "port", - "database", - "schema" - ] - }, "MySqlServer": { "type": "object", "title": "MySqlServer", @@ -1213,11 +1168,8 @@ } }, "required": [ - "host", - "port", "account", "database", - "warehouse", "schema" ] }, From 915ade589ec84a585a4744720b9f04fff2ea045f Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Tue, 17 Sep 2024 12:00:06 +0200 Subject: [PATCH 46/93] Minor fix --- schema/odcs-json-schema-v3.0.0.json | 1 - 1 file changed, 1 deletion(-) diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 13652de..5157ccb 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -1056,7 +1056,6 @@ } }, "required": [ - "host", "database", "schema" ] From 8a5c029bf5982c7d6df55523167d4fac82b7edfb Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Tue, 17 Sep 2024 12:00:41 +0200 Subject: [PATCH 47/93] Minor fix --- docs/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/README.md b/docs/README.md index 26bf3f5..6d50ecd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -925,13 +925,13 @@ Each server type can be customized with different properties such as `host`, `po ## Redshift Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | An optional string describing the server. | -| **database** | Database | Yes | The name of the database. | -| **schema** | Schema | Yes | The name of the schema. | -| **region** | Region | No | AWS region of Redshift server. | -| **account** | Account | No | The account used by the server. | +| Key | UX Label | Required | Description | +|--------------|-----------------|----------|------------------------------------------------------------| +| **database** | Database | Yes | The name of the database. | +| **schema** | Schema | Yes | The name of the schema. | +| **host** | Host | No | An optional string describing the server. | +| **region** | Region | No | AWS region of Redshift server. | +| **account** | Account | No | The account used by the server. | ## S3 Server From 300e3b2d381e2be2cbeb366348fd02ca63ef0673 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 17 Sep 2024 13:27:02 +0200 Subject: [PATCH 48/93] Rename to library --- docs/README.md | 16 ++++++++-------- schema/odcs-json-schema-v3.0.0.json | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/README.md b/docs/README.md index d9b67b7..ac62c87 100644 --- a/docs/README.md +++ b/docs/README.md @@ -299,12 +299,12 @@ This section describes data quality rules & parameters. They are tightly linked Data quality rules support different levels/stages of data quality attributes: - __Text__: A human-readable text that describes the quality of the data. - - __Default__ rules: A maintained library of commonly-used predefined quality attributes such as `rowCount`, `unique`, `freshness`, and more. + - __Library__ rules: A maintained library of commonly-used predefined quality attributes such as `rowCount`, `unique`, `freshness`, and more. - __SQL__: An individual SQL query that returns a value that can be compared. Can be extended to `Python` or other. - __Custom__: Quality attributes that are vendor-specific, such as Soda, Great Expectations, dbt tests, or Montecarlo monitors. ### Text -A human-readable text that describes the quality of the data. Later in the development process, these might be translated into an executable check (such as `sql`), a default rule, or checked through an AI engine. +A human-readable text that describes the quality of the data. Later in the development process, these might be translated into an executable check (such as `sql`), a library rule, or checked through an AI engine. ```yaml quality: @@ -312,7 +312,7 @@ quality: description: The email address was verified by the system. ``` -### Default data quality rules +### Library ODCS will provide a set of predefined rules commonly used in data quality checks, designed to be compatible with all major data quality engines. This simplifies the work for data engineers by eliminating the need to manually write SQL queries. #### Property-level @@ -323,7 +323,7 @@ No more than 10 duplicate names. ```yaml quality: -- type: default # optional and default value for data quality rules +- type: library # optional and default value for data quality rules rule: duplicateCount mustBeLessThan: 10 name: Fewer than 10 duplicate names @@ -427,8 +427,8 @@ Acronyms: |quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | |quality.name |Name | No | A short name for the rule. | |quality.description |Description | No | Describe the quality check to be completed. | -|quality.type |Type | No | Type of DQ rule. Valid values are `default` (default), `text`, `sql`, and `custom`. | -|quality.rule |Rule name | No | Required for `default` DQ rules: the name of the rule to be executed. | +|quality.type |Type | No | Type of DQ rule. Valid values are `library` (default), `text`, `sql`, and `custom`. | +|quality.rule |Rule name | No | Required for `library` DQ rules: the name of the rule to be executed. | |quality.\ |See below | No | Multiple values are allowed for the **property**, the value is the one to compare to. | |quality.unit |Unit | No | Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed. | |quality.validValues |Valid values | No | Static list of valid values. | @@ -492,8 +492,8 @@ quality: ``` -#### Default Rules -Bitol has the ambition of creating a standard set of default data quality rules. Join the working group around [RFC #0012](https://github.com/bitol-io/tsc/blob/main/rfcs/0012-implicit-dq-rules.md). +#### Library Rules +Bitol has the ambition of creating a library of common data quality rules. Join the working group around [RFC #0012](https://github.com/bitol-io/tsc/blob/main/rfcs/0012-implicit-dq-rules.md). ## Support & communication channels diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index f1894ab..b8739f7 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -1808,8 +1808,8 @@ "type": { "type": "string", "description": "The type of quality check.", - "enum": ["text", "predefined", "sql", "custom"], - "default": "predefined" + "enum": ["text", "library", "sql", "custom"], + "default": "library" }, "name": { "type": "string", @@ -1867,12 +1867,12 @@ "if": { "properties": { "type": { - "const": "predefined" + "const": "library" } } }, "then": { - "$ref": "#/$defs/DataQualityPredefined" + "$ref": "#/$defs/DataQualityLibrary" } }, { @@ -1910,7 +1910,7 @@ "$ref": "#/$defs/DataQuality" } }, - "DataQualityPredefined": { + "DataQualityLibrary": { "type": "object", "properties": { "rule": { From 0dc850afb8cfd249f0f603fc1164243907d159d8 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 17 Sep 2024 13:36:32 +0200 Subject: [PATCH 49/93] Add Data Contract Manager to Vendor list. --- vendors.md | 1 + 1 file changed, 1 insertion(+) diff --git a/vendors.md b/vendors.md index 98c86a0..7af690a 100644 --- a/vendors.md +++ b/vendors.md @@ -10,6 +10,7 @@ catalogs, data quality platforms, security tools, and more. * [Data Caterer](https://data.catering/setup/guide/data-source/metadata/open-data-contract-standard/) - Test data management tool using data contracts as a metadata source * [Data Contract CLI](https://cli.datacontract.com) - Open Source tooling around data contracts +* [Data Contract Manager](https://datacontract-manager.com) - Professional data contract management tool with Data Marketplace, Access Management, and Data Governance AI. * [DQC.ai | DQ PLATFORM](https://www.dqc.ai/dqc-platform) - [Enhancing Data Quality with ODCS: A Standard Ensured by the DQ Platform ](https://www.dqc.ai/post/enhancing-data-quality-with-odcs-a-standard-ensured-by-the-dq-platform) From 4f7e0c80809614e21a8312fd75fee2ffcb951638 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 17 Sep 2024 07:43:32 -0400 Subject: [PATCH 50/93] Update column-accuracy.odcs.yaml --- docs/examples/quality/column-accuracy.odcs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/quality/column-accuracy.odcs.yaml b/docs/examples/quality/column-accuracy.odcs.yaml index bcec5d8..c0232d8 100644 --- a/docs/examples/quality/column-accuracy.odcs.yaml +++ b/docs/examples/quality/column-accuracy.odcs.yaml @@ -19,7 +19,7 @@ schema: logicalType: number physicalType: float(3,2) quality: - - type: predefined + - type: library rule: between description: 'This name should contain positive values under 500' dimension: accuracy From 2280d63d5325d3599b8ad3abed38ae8a61efb856 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Tue, 17 Sep 2024 20:01:25 +0800 Subject: [PATCH 51/93] Add in missing attributes for data quality checks, update examples to use library instead of predefined --- docs/examples/all/full-example.odcs.yaml | 4 +- .../quality/column-accuracy.odcs.yaml | 2 +- schema/odcs-json-schema-v3.0.0.json | 106 +++++++++++++----- 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index 09362f0..efa90d6 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -98,7 +98,7 @@ schema: - rule: nullCheck description: column should not contain null values dimension: completeness # dropdown 7 values - type: predefined + type: library severity: error businessImpact: operational schedule: 0 20 * * * @@ -112,7 +112,7 @@ schema: value: Greater than quality: - rule: countCheck - type: predefined + type: library description: Ensure row count is within expected volume range dimension: completeness method: reconciliation diff --git a/docs/examples/quality/column-accuracy.odcs.yaml b/docs/examples/quality/column-accuracy.odcs.yaml index bcec5d8..c0232d8 100644 --- a/docs/examples/quality/column-accuracy.odcs.yaml +++ b/docs/examples/quality/column-accuracy.odcs.yaml @@ -19,7 +19,7 @@ schema: logicalType: number physicalType: float(3,2) quality: - - type: predefined + - type: library rule: between description: 'This name should contain positive values under 500' dimension: accuracy diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 5157ccb..b2ccae3 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -1756,15 +1756,20 @@ "DataQuality": { "type": "object", "properties": { - "type": { - "type": "string", - "description": "The type of quality check.", - "enum": ["text", "predefined", "sql", "custom"], - "default": "predefined" + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" }, - "name": { + "businessImpact": { "type": "string", - "description": "Name of the data quality check." + "description": "Consequences of the rule failure.", + "examples": ["operational", "regulatory"] + }, + "customProperties": { + "type": "array", + "description": "Additional properties required for rule execution.", + "items": { + "$ref": "#/$defs/CustomProperty" + } }, "description": { "type": "string", @@ -1775,20 +1780,14 @@ "description": "The key performance indicator (KPI) or dimension for data quality.", "enum": ["accuracy", "completeness", "conformity", "consistency", "coverage", "timeliness", "uniqueness"] }, - "severity": { - "type": "string", - "description": "The severance of the quality rule.", - "examples": ["info", "warning", "error"] - }, - "businessImpact": { - "type": "string", - "description": "Consequences of the rule failure.", - "examples": ["operational", "regulatory"] - }, "method": { "type": "string", "examples": ["reconciliation"] }, + "name": { + "type": "string", + "description": "Name of the data quality check." + }, "schedule": { "type": "string", "description": "Rule execution schedule details.", @@ -1799,18 +1798,24 @@ "description": "The name or type of scheduler used to start the data quality check.", "examples": ["cron"] }, - "authoritativeDefinitions": { - "$ref": "#/$defs/AuthoritativeDefinitions" + "severity": { + "type": "string", + "description": "The severance of the quality rule.", + "examples": ["info", "warning", "error"] }, "tags": { "$ref": "#/$defs/Tags" }, - "customProperties": { - "type": "array", - "description": "Additional properties required for rule execution.", - "items": { - "$ref": "#/$defs/CustomProperty" - } + "type": { + "type": "string", + "description": "The type of quality check. 'text' is human-readable text that describes the quality of the data. 'library' is a set of maintained predefined quality attributes such as row count or unique. 'sql' is an individual SQL query that returns a value that can be compared. 'custom' is quality attributes that are vendor-specific, such as Soda or Great Expectations.", + "enum": ["text", "library", "sql", "custom"], + "default": "library" + }, + "unit": { + "type": "string", + "description": "Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed.", + "examples": ["rows", "percent"] } }, "allOf": [ @@ -1818,12 +1823,12 @@ "if": { "properties": { "type": { - "const": "predefined" + "const": "library" } } }, "then": { - "$ref": "#/$defs/DataQualityPredefined" + "$ref": "#/$defs/DataQualityLibrary" } }, { @@ -1861,12 +1866,55 @@ "$ref": "#/$defs/DataQuality" } }, - "DataQualityPredefined": { + "DataQualityLibrary": { "type": "object", "properties": { "rule": { "type": "string", - "description": "Define a data quality check based on the predefined rules as per ODCS." + "description": "Define a data quality check based on the predefined rules as per ODCS.", + "examples": ["duplicateCount", "validValues", "rowCount"] + }, + "mustBe": { + "description": "Must be equal to the value to be valid. When using numbers, it is equivalent to '='." + }, + "mustNotBe": { + "description": "Must not be equal to the value to be valid. When using numbers, it is equivalent to '!='." + }, + "mustBeGreaterThan": { + "type": "number", + "description": "Must be greater than the value to be valid. It is equivalent to '>'." + }, + "mustBeGreaterOrEqualTo": { + "type": "number", + "description": "Must be greater than or equal to the value to be valid. It is equivalent to '>='." + }, + "mustBeLessThan": { + "type": "number", + "description": "Must be less than the value to be valid. It is equivalent to '<'." + }, + "mustBeLessOrEqualTo": { + "type": "number", + "description": "Must be less than or equal to the value to be valid. It is equivalent to '<='." + }, + "mustBeBetween": { + "type": "array", + "description": "Must be between the two numbers to be valid. Smallest number first in the array.", + "minItems": 2, + "maxItems": 2, + "uniqueItems": true, + "items": { + "type": "number" + } + }, + "mustNotBeBetween": { + "type": "array", + "description": "Must not be between the two numbers to be valid. Smallest number first in the array.", + "minItems": 2, + "maxItems": 2, + "uniqueItems": true, + "items": { + "type": "number" + } } }, "required": ["rule"] From 06b9141eee0295d91bffa2339ac4fa51d751d173 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 17 Sep 2024 09:21:27 -0400 Subject: [PATCH 52/93] Some cleanup of the server section for consistency/ --- docs/README.md | 305 ++++++++++++++++++++++++++++--------------------- 1 file changed, 176 insertions(+), 129 deletions(-) diff --git a/docs/README.md b/docs/README.md index 5902338..898043e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -697,7 +697,7 @@ slaProperties: | slaProperties.element | Element(s) | No | Element(s) to check on. Multiple elements should be extremely rare and, if so, separated by commas. | | slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | -## Infrastructure & servers +## Infrastructure & Servers The `servers` element describes where the data protected by this data contract is *physically* located. That metadata helps to know where the data is so that a data consumer can discover the data and a platform engineer can automate access. @@ -727,9 +727,9 @@ servers: #### Common Server Properties -- **type**: The type of server. Valid values include various server technologies like `athena`, `bigquery`, `postgres`, etc. +- **type**: The type of server. Valid values include various server technologies like `athena`, `bigquery`, `postgresql`, etc. - **description**: A description of the server. -- **environment**: The environment where the server operates (e.g., `prod`, `dev`, `uat`). +- **environment**: The environment where the server operates (e.g., `prod`, `dev`, `uat`). There are no set values. - **roles**: An array of roles that have access to the server. - **customProperties**: Any additional custom properties specific to the server. @@ -737,25 +737,27 @@ servers: Each server type can be customized with different properties such as `host`, `port`, `database`, and `schema`, depending on the server technology in use. Refer to the specific documentation for each server type for additional configurations. -#### Server Types +### Specific Server Properties & Types +If your server is not in the list, please use [custom](#custom-server) and suggest it as an improvement. Possible values for `type` are: - [athena](#athena-server) - [azure](#azure-server) - [bigquery](#bigquery-server) - [clickhouse](#clickhouse-server) - [databricks](#databricks-server) +- [db2](#ibmdb2-server) - [denodo](#denodo-server) - [dremio](#dremio-server) - [duckdb](#duckdb-server) - [glue](#glue-server) -- [googlecloudsql](#googlecloudsql-server) -- [ibmdb2](#ibmdb2-server) +- [cloudsql](#googlecloudsql-server) +- [infomix](#informix) - [kafka](#kafka-server) - [kinesis](#kinesis-server) - [local](#local-server) - [mysql](#mysql-server) - [oracle](#oracle-server) -- [postgres](#postgres-server) +- [postgresql](#postgres-server) - [presto](#presto-server) - [pubsub](#pubsub-server) - [redshift](#redshift-server) @@ -767,237 +769,279 @@ Each server type can be customized with different properties such as `host`, `po - [trino](#trino-server) - [vertica](#vertica-server) ---- +#### Athena Server +[Amazon Athena](https://docs.aws.amazon.com/athena/latest/ug/what-is.html) is an interactive query service that makes it easy to analyze data directly in Amazon Simple Storage Service (Amazon S3) using standard SQL. With a few actions in the AWS Management Console, you can point Athena at your data stored in Amazon S3 and begin using standard SQL to run ad-hoc queries and get results in seconds. +| Key | UX Label | Required | Description | +|--------------|-----------------|------------|------------------------------------------------------------| +| schema | Schema | Yes | Identify the schema in the data source in which your tables exist. | +| stagingDir | Stagingdir | No | Amazon Athena automatically stores query results and metadata information for each query that runs in a query result location that you can specify in Amazon S3. | +| catalog | Catalog | No | Identify the name of the Data Source, also referred to as a Catalog. | +| regionName | Regionname | No | The region your AWS account uses. | -## Athena Server +#### Azure Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **schema** | Schema | Yes | Identify the schema in the data source in which your tables exist. | -| **stagingDir** | Stagingdir | No | Amazon Athena automatically stores query results and metadata information for each query that runs in a query result location that you can specify in Amazon S3. | -| **catalog** | Catalog | No | Identify the name of the Data Source, also referred to as a Catalog. | -| **regionName** | Regionname | No | The region your AWS account uses. | +| location | Location | Yes | Fully qualified path to Azure Blob Storage or Azure Data Lake Storage (ADLS), supports globs. | +| format | Format | Yes | File format. | +| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | + +#### BigQuery Server +[BigQuery](https://cloud.google.com/bigquery) is a fully managed, AI-ready data analytics platform that helps you maximize value from your data and is designed to be multi-engine, multi-format, and multi-cloud. -## Azure Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **location** | Location | Yes | Fully qualified path to Azure Blob Storage or Azure Data Lake Storage (ADLS), supports globs. | -| **format** | Format | Yes | File format. | -| **delimiter** | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | +| project | Project | Yes | The GCP project name. | +| dataset | Dataset | Yes | The GCP dataset name. | -## Bigquery Server +#### ClickHouse Server +[ClickHouse](https://clickhouse.com/) is an open-source column-oriented database management system that allows generating analytical data reports in real-time. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **project** | Project | Yes | The GCP project name. | -| **dataset** | Dataset | Yes | The GCP dataset name. | +| host | Host | Yes | The host of the ClickHouse server. | +| port | Port | Yes | The port to the ClickHouse server. | +| database | Database | Yes | The name of the database. | -## Clickhouse Server +#### Google Cloud SQL | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the ClickHouse server. | -| **port** | Port | Yes | The port to the ClickHouse server. | -| **database** | Database | Yes | The name of the database. | +| host | Host | Yes | The host of the Google Cloud Sql server. | +| port | Port | Yes | The port of the Google Cloud Sql server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | Yes | The name of the schema. | -## Databricks Server +#### Databricks Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **catalog** | Catalog | Yes | The name of the Hive or Unity catalog | -| **schema** | Schema | Yes | The schema name in the catalog | -| **host** | Host | No | The Databricks host | +| catalog | Catalog | Yes | The name of the Hive or Unity catalog | +| schema | Schema | Yes | The schema name in the catalog | +| host | Host | No | The Databricks host | -## Denodo Server +#### IBM Db2 Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the Denodo server. | -| **port** | Port | Yes | The port of the Denodo server. | -| **database** | Database | No | The name of the database. | +| host | Host | Yes | The host of the IBM DB2 server. | +| port | Port | Yes | The port of the IBM DB2 server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | No | The name of the schema. | -## Dremio Server +#### Denodo Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the Dremio server. | -| **port** | Port | Yes | The port of the Dremio server. | -| **schema** | Schema | No | The name of the schema. | +| host | Host | Yes | The host of the Denodo server. | +| port | Port | Yes | The port of the Denodo server. | +| database | Database | No | The name of the database. | -## Duckdb Server +#### Dremio Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **database** | Database | Yes | Path to duckdb database file. | -| **schema** | Schema | No | The name of the schema. | +| host | Host | Yes | The host of the Dremio server. | +| port | Port | Yes | The port of the Dremio server. | +| schema | Schema | No | The name of the schema. | -## Glue Server +#### DuckDB Server +[DuckDB](https://duckdb.org/) supports a feature-rich SQL dialect complemented with deep integrations into client APIs. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **account** | Account | Yes | The AWS Glue account | -| **database** | Database | Yes | The AWS Glue database name | -| **location** | Location | No | The AWS S3 path. Must be in the form of a URL. | -| **format** | Format | No | The format of the files | +| database | Database | Yes | Path to duckdb database file. | +| schema | Schema | No | The name of the schema. | -## Googlecloudsql Server +#### Amazon Glue | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the Google Cloud Sql server. | -| **port** | Port | Yes | The port of the Google Cloud Sql server. | -| **database** | Database | Yes | The name of the database. | -| **schema** | Schema | Yes | The name of the schema. | +| account | Account | Yes | The AWS Glue account | +| database | Database | Yes | The AWS Glue database name | +| location | Location | No | The AWS S3 path. Must be in the form of a URL. | +| format | Format | No | The format of the files | -## Ibmdb2 Server +#### IBM Informix & HCL Informix +[IBM Informix](https://www.ibm.com/products/informix) is a high performance, always-on, highly scalable and easily embeddable enterprise-class database optimized for the most demanding transactional and analytics workloads. As an object-relational engine, IBM Informix seamlessly integrates the best of relational and object-oriented capabilities enabling the flexible modeling of complex data structures and relationships. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the IBM DB2 server. | -| **port** | Port | Yes | The port of the IBM DB2 server. | -| **database** | Database | Yes | The name of the database. | -| **schema** | Schema | No | The name of the schema. | +| host | Host | Yes | The host to the PostgreSQL server | +| port | Port | Yes | The port to the PostgreSQL server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | No | The name of the schema in the database. | + -## Kafka Server +#### Kafka Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The bootstrap server of the kafka cluster. | -| **topic** | Topic | Yes | The topic name. | -| **format** | Format | No | The format of the messages. | +| host | Host | Yes | The bootstrap server of the kafka cluster. | +| topic | Topic | Yes | The topic name. | +| format | Format | No | The format of the messages. | -## Kinesis Server +#### Amazon Kinesis | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **stream** | Stream | Yes | The name of the Kinesis data stream. | -| **region** | Region | No | AWS region. | -| **format** | Format | No | The format of the record | +| stream | Stream | Yes | The name of the Kinesis data stream. | +| region | Region | No | AWS region. | +| format | Format | No | The format of the record | -## Local Server +#### Local Files | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **path** | Path | Yes | The relative or absolute path to the data file(s). | -| **format** | Format | Yes | The format of the file(s) | +| path | Path | Yes | The relative or absolute path to the data file(s). | +| format | Format | Yes | The format of the file(s) | -## Mysql Server +#### MySQL Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the MySql server. | -| **port** | Port | Yes | The port of the MySql server. | -| **database** | Database | Yes | The name of the database. | +| host | Host | Yes | The host of the MySql server. | +| port | Port | Yes | The port of the MySql server. | +| database | Database | Yes | The name of the database. | -## Oracle Server +#### Oracle | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host to the oracle server | -| **port** | Port | Yes | The port to the oracle server. | -| **serviceName** | Servicename | Yes | The name of the service. | +| host | Host | Yes | The host to the Oracle server | +| port | Port | Yes | The port to the Oracle server. | +| serviceName | Servicename | Yes | The name of the service. | -## Postgres Server +#### PostgreSQL +[PostgreSQL](https://www.postgresql.org/) is a powerful, open source object-relational database system with over 35 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host to the Postgres server | -| **port** | Port | Yes | The port to the Postgres server. | -| **database** | Database | Yes | The name of the database. | -| **schema** | Schema | Yes | The name of the schema in the database. | +| host | Host | Yes | The host to the PostgreSQL server | +| port | Port | Yes | The port to the PostgreSQL server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | No | The name of the schema in the database. | -## Presto Server +#### Presto Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host to the Presto server | -| **catalog** | Catalog | No | The name of the catalog. | -| **schema** | Schema | No | The name of the schema. | +| host | Host | Yes | The host to the Presto server | +| catalog | Catalog | No | The name of the catalog. | +| schema | Schema | No | The name of the schema. | -## Pubsub Server +#### Google Pub/Sub +[Google Cloud](https://cloud.google.com/pubsub) service to Ingest events for streaming into BigQuery, data lakes or operational databases. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **project** | Project | Yes | The GCP project name. | -| **topic** | Topic | Yes | The topic name. | +| project | Project | Yes | The GCP project name. | +| topic | Topic | Yes | The topic name. | -## Redshift Server +#### Amazon Redshift Server +[Amazon Redshift](https://aws.amazon.com/redshift/) is a power data driven decisions with the best price-performance cloud data warehouse. | Key | UX Label | Required | Description | |--------------|-----------------|----------|------------------------------------------------------------| -| **database** | Database | Yes | The name of the database. | -| **schema** | Schema | Yes | The name of the schema. | -| **host** | Host | No | An optional string describing the server. | -| **region** | Region | No | AWS region of Redshift server. | -| **account** | Account | No | The account used by the server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | Yes | The name of the schema. | +| host | Host | No | An optional string describing the server. | +| region | Region | No | AWS region of Redshift server. | +| account | Account | No | The account used by the server. | -## S3 Server +#### Amazon S3 Server and Compatible Servers +[Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) is an object storage service offering industry-leading scalability, data availability, security, and performance. Millions of customers of all sizes and industries store, manage, analyze, and protect any amount of data for virtually any use case, such as data lakes, cloud-native applications, and mobile apps. Other vendors have implemented a compatible implementation of S3. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **location** | Location | Yes | S3 URL, starting with `s3://` | -| **endpointUrl** | Endpointurl | No | The server endpoint for S3-compatible servers. | -| **format** | Format | No | File format. | -| **delimiter** | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | +| location | Location | Yes | S3 URL, starting with `s3://` | +| endpointUrl | Endpointurl | No | The server endpoint for S3-compatible servers. | +| format | Format | No | File format. | +| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | -## Sftp Server +#### SFTP Server +Secure File Transfer Protocol (SFTP) is a network protocol that enables secure and encrypted file transfers between a client and a server. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **location** | Location | Yes | SFTP URL, starting with `sftp://` | -| **format** | Format | No | File format. | -| **delimiter** | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | +| location | Location | Yes | SFTP URL, starting with `sftp://` | +| format | Format | No | File format. | +| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | -## Snowflake Server +#### Snowflake | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host to the Snowflake server | -| **port** | Port | Yes | The port to the Snowflake server. | -| **account** | Account | Yes | The Snowflake account used by the server. | -| **database** | Database | Yes | The name of the database. | -| **warehouse** | Warehouse | Yes | The name of the cluster of resources that is a Snowflake virtual warehouse. | -| **schema** | Schema | Yes | The name of the schema. | +| host | Host | Yes | The host to the Snowflake server | +| port | Port | Yes | The port to the Snowflake server. | +| account | Account | Yes | The Snowflake account used by the server. | +| database | Database | Yes | The name of the database. | +| warehouse | Warehouse | Yes | The name of the cluster of resources that is a Snowflake virtual warehouse. | +| schema | Schema | Yes | The name of the schema. | -## Sqlserver Server +#### Microsoft SQL Server +[Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server/sql-server-downloads) is a proprietary relational database management system developed by Microsoft. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host to the database server | -| **database** | Database | Yes | The name of the database. | -| **schema** | Schema | Yes | The name of the schema in the database. | -| **port** | Port | No | The port to the database server. | +| host | Host | Yes | The host to the database server | +| database | Database | Yes | The name of the database. | +| schema | Schema | Yes | The name of the schema in the database. | +| port | Port | No | The port to the database server. | -## Synapse Server +#### Synapse Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the Synapse server. | -| **port** | Port | Yes | The port of the Synapse server. | -| **database** | Database | Yes | The name of the database. | +| host | Host | Yes | The host of the Synapse server. | +| port | Port | Yes | The port of the Synapse server. | +| database | Database | Yes | The name of the database. | -## Trino Server +#### Trino Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The Trino host URL. | -| **port** | Port | Yes | The Trino port. | -| **catalog** | Catalog | Yes | The name of the catalog. | -| **schema** | Schema | Yes | The name of the schema in the database. | +| host | Host | Yes | The Trino host URL. | +| port | Port | Yes | The Trino port. | +| catalog | Catalog | Yes | The name of the catalog. | +| schema | Schema | Yes | The name of the schema in the database. | -## Vertica Server +#### Vertica Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| **host** | Host | Yes | The host of the Vertica server. | -| **port** | Port | Yes | The port of the Vertica server. | -| **database** | Database | Yes | The name of the database. | -| **schema** | Schema | Yes | The name of the schema. | - - - +| host | Host | Yes | The host of the Vertica server. | +| port | Port | Yes | The port of the Vertica server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | Yes | The name of the schema. | + +#### Custom Server + +| Key | UX Label | Required | Description | +|--------------|-------------------|------------|------------------------------------------------------------| +| account | Account | No | Account used by the server. | +| catalog | Catalog | No | Name of the catalog. | +| database | Database | No | Name of the database. | +| dataset | Dataset | No | Name of the dataset. | +| delimiter | Delimiter | No | Delimiter. | +| endpointUrl | Endpoint URL | No | Server endpoint. | +| format | Format | No | File format. | +| host | Host | No | Host name or IP address. | +| location | Location | No | A URL to a location. | +| path | Path | No | Relative or absolute path to the data file(s). | +| project | Project | No | Project name. | +| region | Region | No | Cloud region. | +| regionName | Regionname | No | Region name. | +| schema | Schema | No | Name of the schema. | +| serviceName | Servicename | No | Name of the service. | +| stagingDir | Staging directory | No | Staging directory. | +| stream | Stream | No | Name of the data stream. | +| topic | Topic | No | Topic name. | +| warehouse | Warehouse | No | Name of the cluster or warehouse. | + +If you need another property, use [custom properties](#custom-properties). ## Custom Properties @@ -1043,3 +1087,6 @@ contractCreatedTs: 2022-11-15 02:59:43 ## Full example [Check full example here.](examples/all/full-example.yaml) + + +All trademarks are the property of their respective owners. \ No newline at end of file From 3a0627ba81d1b96d7f1e1ffd5d365a84afb90c24 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 17 Sep 2024 09:33:24 -0400 Subject: [PATCH 53/93] More cleanup --- docs/README.md | 69 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/docs/README.md b/docs/README.md index 898043e..1742c93 100644 --- a/docs/README.md +++ b/docs/README.md @@ -701,13 +701,13 @@ slaProperties: The `servers` element describes where the data protected by this data contract is *physically* located. That metadata helps to know where the data is so that a data consumer can discover the data and a platform engineer can automate access. -A `server` describes a single dataset on a specific environment and a specific technology. The `servers` element can contain multiple servers, each with its own configuration. +An entry in `servers` describes a single dataset on a specific environment and a specific technology. The `servers` element can contain multiple servers, each with its own configuration. The typical ways of using the top level `servers` element are as follows: - **Single Server:** The data contract protects a specific dataset at a specific location. *Example:* a CSV file on an SFTP server. -- **Multiple Environments:** The data contract makes sure that the data is protected in all environments. *Example:* a data product with data in a dev, uat, and prod environment on Databricks. -- **Different Technologies:** The data contract makes sure that regardless of the offered technology, it still holds. *Example:* a data product offers its data in a kafka topic and in a BigQuery table that should have the same structure and content. -- **Different Technologies and Multiple Environments:** The data contract makes sure that regardless of the offered technology and environment, it still holds. *Example:* a data product offers its data in a kafka topic and in a BigQuery table that should have the same structure and content in dev, uat, and prod. +- **Multiple Environments:** The data contract makes sure that the data is protected in all environments. *Example:* a data product with data in a dev(elopment), UAT, and prod(uction) environment on Databricks. +- **Different Technologies:** The data contract makes sure that regardless of the offered technology, it still holds. *Example:* a data product offers its data in a Kafka topic and in a BigQuery table that should have the same structure and content. +- **Different Technologies and Multiple Environments:** The data contract makes sure that regardless of the offered technology and environment, it still holds. *Example:* a data product offers its data in a Kafka topic and in a BigQuery table that should have the same structure and content in dev(elopment), UAT, and prod(uction). ### General Server Structure @@ -730,7 +730,7 @@ servers: - **type**: The type of server. Valid values include various server technologies like `athena`, `bigquery`, `postgresql`, etc. - **description**: A description of the server. - **environment**: The environment where the server operates (e.g., `prod`, `dev`, `uat`). There are no set values. -- **roles**: An array of roles that have access to the server. +- **roles**: An optional array of roles that have access to the server. - **customProperties**: Any additional custom properties specific to the server. ### Specific Server Properties @@ -869,11 +869,9 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host to the PostgreSQL server | -| port | Port | Yes | The port to the PostgreSQL server. | -| database | Database | Yes | The name of the database. | -| schema | Schema | No | The name of the schema in the database. | - +| host | Host | Yes | The host to the Informix server. | +| port | Port | No | The port to the Informix server. Defaults to 9088. | +| database | Database | Yes | The name of the database. | #### Kafka Server @@ -902,8 +900,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the MySql server. | -| port | Port | Yes | The port of the MySql server. | +| host | Host | Yes | The host of the MySql server. | +| port | Port | No | The port of the MySql server. Defaults to 3306. | | database | Database | Yes | The name of the database. | #### Oracle @@ -912,7 +910,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge |--------------|-----------------|------------|------------------------------------------------------------| | host | Host | Yes | The host to the Oracle server | | port | Port | Yes | The port to the Oracle server. | -| serviceName | Servicename | Yes | The name of the service. | +| serviceName | Service Name | Yes | The name of the service. | #### PostgreSQL [PostgreSQL](https://www.postgresql.org/) is a powerful, open source object-relational database system with over 35 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance. @@ -920,7 +918,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| | host | Host | Yes | The host to the PostgreSQL server | -| port | Port | Yes | The port to the PostgreSQL server. | +| port | Port | No | The port to the PostgreSQL server. Defaults to 5432. | | database | Database | Yes | The name of the database. | | schema | Schema | No | The name of the schema in the database. | @@ -966,7 +964,7 @@ Secure File Transfer Protocol (SFTP) is a network protocol that enables secure a | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| location | Location | Yes | SFTP URL, starting with `sftp://` | +| location | Location | Yes | SFTP URL, starting with `sftp://`. The URL should include the port number. | | format | Format | No | File format. | | delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | @@ -987,9 +985,9 @@ Secure File Transfer Protocol (SFTP) is a network protocol that enables secure a | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| | host | Host | Yes | The host to the database server | +| port | Port | No | The port to the database server. Defaults to 1433. | | database | Database | Yes | The name of the database. | | schema | Schema | Yes | The name of the schema in the database. | -| port | Port | No | The port to the database server. | #### Synapse Server @@ -1019,26 +1017,27 @@ Secure File Transfer Protocol (SFTP) is a network protocol that enables secure a #### Custom Server -| Key | UX Label | Required | Description | -|--------------|-------------------|------------|------------------------------------------------------------| -| account | Account | No | Account used by the server. | -| catalog | Catalog | No | Name of the catalog. | -| database | Database | No | Name of the database. | -| dataset | Dataset | No | Name of the dataset. | -| delimiter | Delimiter | No | Delimiter. | -| endpointUrl | Endpoint URL | No | Server endpoint. | -| format | Format | No | File format. | -| host | Host | No | Host name or IP address. | -| location | Location | No | A URL to a location. | -| path | Path | No | Relative or absolute path to the data file(s). | -| project | Project | No | Project name. | -| region | Region | No | Cloud region. | -| regionName | Regionname | No | Region name. | -| schema | Schema | No | Name of the schema. | -| serviceName | Servicename | No | Name of the service. | -| stagingDir | Staging directory | No | Staging directory. | +| Key | UX Label | Required | Description | +|--------------|-------------------|------------|---------------------------------------------------------------------| +| account | Account | No | Account used by the server. | +| catalog | Catalog | No | Name of the catalog. | +| database | Database | No | Name of the database. | +| dataset | Dataset | No | Name of the dataset. | +| delimiter | Delimiter | No | Delimiter. | +| endpointUrl | Endpoint URL | No | Server endpoint. | +| format | Format | No | File format. | +| host | Host | No | Host name or IP address. | +| location | Location | No | A URL to a location. | +| path | Path | No | Relative or absolute path to the data file(s). | +| port | Port | No | Port to the server. No default value is assumed for custom servers. | +| project | Project | No | Project name. | +| region | Region | No | Cloud region. | +| regionName | Regionname | No | Region name. | +| schema | Schema | No | Name of the schema. | +| serviceName | Servicename | No | Name of the service. | +| stagingDir | Staging directory | No | Staging directory. | | stream | Stream | No | Name of the data stream. | -| topic | Topic | No | Topic name. | +| topic | Topic | No | Topic name. | | warehouse | Warehouse | No | Name of the cluster or warehouse. | If you need another property, use [custom properties](#custom-properties). From 818b896752375d50c6c85cbedd4165174e60c485 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 17 Sep 2024 09:41:43 -0400 Subject: [PATCH 54/93] Update README.md --- docs/README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1742c93..cf72800 100644 --- a/docs/README.md +++ b/docs/README.md @@ -769,7 +769,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge - [trino](#trino-server) - [vertica](#vertica-server) -#### Athena Server +#### Amazon Athena Server [Amazon Athena](https://docs.aws.amazon.com/athena/latest/ug/what-is.html) is an interactive query service that makes it easy to analyze data directly in Amazon Simple Storage Service (Amazon S3) using standard SQL. With a few actions in the AWS Management Console, you can point Athena at your data stored in Amazon S3 and begin using standard SQL to run ad-hoc queries and get results in seconds. | Key | UX Label | Required | Description | @@ -779,7 +779,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | catalog | Catalog | No | Identify the name of the Data Source, also referred to as a Catalog. | | regionName | Regionname | No | The region your AWS account uses. | -#### Azure Server +#### Azure Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| @@ -787,16 +787,15 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | format | Format | Yes | File format. | | delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | -#### BigQuery Server +#### Google BigQuery [BigQuery](https://cloud.google.com/bigquery) is a fully managed, AI-ready data analytics platform that helps you maximize value from your data and is designed to be multi-engine, multi-format, and multi-cloud. - | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| project | Project | Yes | The GCP project name. | +| project | Project | Yes | The Google Cloud Platform (GCP) project name. | | dataset | Dataset | Yes | The GCP dataset name. | -#### ClickHouse Server +#### ClickHouse Server [ClickHouse](https://clickhouse.com/) is an open-source column-oriented database management system that allows generating analytical data reports in real-time. | Key | UX Label | Required | Description | @@ -806,11 +805,12 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | database | Database | Yes | The name of the database. | #### Google Cloud SQL +[Google Cloud SQL](https://cloud.google.com/sql) is a fully managed, cost-effective relational database service for PostgreSQL, MySQL, and SQL Server. | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the Google Cloud Sql server. | -| port | Port | Yes | The port of the Google Cloud Sql server. | +| host | Host | Yes | The host of the Google Cloud SQL server. | +| port | Port | Yes | The port of the Google Cloud SQL server. | | database | Database | Yes | The name of the database. | | schema | Schema | Yes | The name of the schema. | @@ -1073,15 +1073,15 @@ This section covers other properties you may find in a data contract. ### Example ```YAML -contractCreatedTs: 2022-11-15 02:59:43 +contractCreatedTs: 2024-09-17T11:58:08Z ``` ### Other properties definition -| Key | UX label | Required | Description | -|---------------------------|----------------------|----------|--------------------------------------------------------------| -| contractCreatedTs | Contract Created UTC | No | Timestamp in UTC of when the data contract was created. | +| Key | UX label | Required | Description | +|---------------------------|----------------------|----------|-------------------------------------------------------------------------| +| contractCreatedTs | Contract Created UTC | No | Timestamp in UTC of when the data contract was created, using ISO 8601. | ## Full example From f1433d1c65163414ff6cf7a5b7d3152418a0ec9d Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 17 Sep 2024 09:44:29 -0400 Subject: [PATCH 55/93] Update README.md --- docs/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/README.md b/docs/README.md index cf72800..d80419b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -751,7 +751,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge - [duckdb](#duckdb-server) - [glue](#glue-server) - [cloudsql](#googlecloudsql-server) -- [infomix](#informix) +- [infomix](#informix-server) - [kafka](#kafka-server) - [kinesis](#kinesis-server) - [local](#local-server) @@ -769,7 +769,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge - [trino](#trino-server) - [vertica](#vertica-server) -#### Amazon Athena Server +#### Amazon Athena Server [Amazon Athena](https://docs.aws.amazon.com/athena/latest/ug/what-is.html) is an interactive query service that makes it easy to analyze data directly in Amazon Simple Storage Service (Amazon S3) using standard SQL. With a few actions in the AWS Management Console, you can point Athena at your data stored in Amazon S3 and begin using standard SQL to run ad-hoc queries and get results in seconds. | Key | UX Label | Required | Description | @@ -779,7 +779,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | catalog | Catalog | No | Identify the name of the Data Source, also referred to as a Catalog. | | regionName | Regionname | No | The region your AWS account uses. | -#### Azure Server +#### Azure Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| @@ -787,7 +787,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | format | Format | Yes | File format. | | delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | -#### Google BigQuery +#### Google BigQuery [BigQuery](https://cloud.google.com/bigquery) is a fully managed, AI-ready data analytics platform that helps you maximize value from your data and is designed to be multi-engine, multi-format, and multi-cloud. | Key | UX Label | Required | Description | @@ -795,7 +795,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | project | Project | Yes | The Google Cloud Platform (GCP) project name. | | dataset | Dataset | Yes | The GCP dataset name. | -#### ClickHouse Server +#### ClickHouse Server [ClickHouse](https://clickhouse.com/) is an open-source column-oriented database management system that allows generating analytical data reports in real-time. | Key | UX Label | Required | Description | @@ -814,7 +814,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | database | Database | Yes | The name of the database. | | schema | Schema | Yes | The name of the schema. | -#### Databricks Server +#### Databricks Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| @@ -822,7 +822,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | schema | Schema | Yes | The schema name in the catalog | | host | Host | No | The Databricks host | -#### IBM Db2 Server +#### IBM Db2 Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| @@ -831,7 +831,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | database | Database | Yes | The name of the database. | | schema | Schema | No | The name of the schema. | -#### Denodo Server +#### Denodo Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| @@ -839,7 +839,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | port | Port | Yes | The port of the Denodo server. | | database | Database | No | The name of the database. | -#### Dremio Server +#### Dremio Server | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| @@ -847,7 +847,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | port | Port | Yes | The port of the Dremio server. | | schema | Schema | No | The name of the schema. | -#### DuckDB Server +#### DuckDB Server [DuckDB](https://duckdb.org/) supports a feature-rich SQL dialect complemented with deep integrations into client APIs. | Key | UX Label | Required | Description | From 674dcbc0d4bbc50d77e248e9cf423a34c3f3fd95 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 17 Sep 2024 10:10:43 -0400 Subject: [PATCH 56/93] Typo - thanks Jochen --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index d80419b..b65639c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -751,7 +751,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge - [duckdb](#duckdb-server) - [glue](#glue-server) - [cloudsql](#googlecloudsql-server) -- [infomix](#informix-server) +- [informix](#informix-server) - [kafka](#kafka-server) - [kinesis](#kinesis-server) - [local](#local-server) From a739a5a9ef0880ec9c374b612ddec7e63dd8ac49 Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Mon, 30 Sep 2024 14:58:03 +0200 Subject: [PATCH 57/93] Last changes for server --- docs/README.md | 7 + schema/odcs-json-schema-v3.0.0.json | 192 +++++++++++++++++++++++++++- 2 files changed, 193 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index 6d50ecd..1c9c48d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -739,6 +739,7 @@ Each server type can be customized with different properties such as `host`, `po #### Server Types +- [api](#api-server) - [athena](#athena-server) - [azure](#azure-server) - [bigquery](#bigquery-server) @@ -769,6 +770,12 @@ Each server type can be customized with different properties such as `host`, `po --- +## API Server + +| Key | UX Label | Required | Description | +|----------------|------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **location** | Location | Yes | URL to the API | + ## Athena Server diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 5157ccb..940b30a 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -140,10 +140,10 @@ "type": "string", "description": "Type of the server.", "enum": [ - "athena", "azure", "bigquery", "clickhouse", "databricks", "denodo", "dremio", - "duckdb", "glue", "googlecloudsql", "ibmdb2", "kafka", "kinesis", "local", - "mysql", "oracle", "postgres", "presto", "pubsub", - "redshift", "s3", "sftp", "snowflake", "sqlserver", "synapse", "trino", "vertica" + "api", "athena", "azure", "bigquery", "clickhouse", "databricks", "denodo", "dremio", + "duckdb", "glue", "cloudsql", "db2", "informix", "kafka", "kinesis", "local", + "mysql", "oracle", "postgresql", "postgres", "presto", "pubsub", + "redshift", "s3", "sftp", "snowflake", "sqlserver", "synapse", "trino", "vertica", "custom" ] }, "description": { @@ -167,6 +167,19 @@ } }, "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "api" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/ApiServer" + } + }, { "if": { "properties": { @@ -288,7 +301,7 @@ "if": { "properties": { "type": { - "const": "googlecloudsql" + "const": "cloudsql" } }, "required": ["type"] @@ -301,7 +314,7 @@ "if": { "properties": { "type": { - "const": "ibmdb2" + "const": "db2" } }, "required": ["type"] @@ -310,6 +323,33 @@ "$ref": "#/$defs/ServerSource/IBMDB2Server" } }, + { + "if": { + "properties": { + "type": { + "const": "informix" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/InformixServer" + } + }, + + { + "if": { + "properties": { + "type": { + "const": "custom" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/CustomServer" + } + }, { "if": { "properties": { @@ -375,6 +415,19 @@ "$ref": "#/$defs/ServerSource/OracleServer" } }, + { + "if": { + "properties": { + "type": { + "const": "postgresql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/PostgresServer" + } + }, { "if": { "properties": { @@ -522,6 +575,23 @@ "required": ["server", "type"] }, "ServerSource": { + "ApiServer": { + "type": "object", + "title": "AthenaServer", + "properties": { + "location": { + "type": "string", + "format": "uri", + "description": "The url to the API.", + "examples": [ + "https://api.example.com/v1" + ] + } + }, + "required": [ + "location" + ] + }, "AthenaServer": { "type": "object", "title": "AthenaServer", @@ -815,6 +885,116 @@ "database" ] }, + "InformixServer": { + "type": "object", + "title": "InformixServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the Informix server. " + }, + "port": { + "type": "integer", + "description": "The port to the Informix server. Defaults to 9088." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "database" + ] + }, + "CustomServer": { + "type": "object", + "title": "CustomServer", + "properties": { + "account": { + "type": "string", + "description": "Account used by the server." + }, + "catalog": { + "type": "string", + "description": "Name of the catalog." + }, + "database": { + "type": "string", + "description": "Name of the database." + }, + "dataset": { + "type": "string", + "description": "Name of the dataset." + }, + "delimiter": { + "type": "string", + "description": "Delimiter." + }, + "endpointUrl": { + "type": "string", + "description": "Server endpoint.", + "format": "uri" + }, + "format": { + "type": "string", + "description": "File format." + }, + "host": { + "type": "string", + "description": "Host name or IP address." + }, + "location": { + "type": "string", + "description": "A URL to a location.", + "format": "uri" + }, + "path": { + "type": "string", + "description": "Relative or absolute path to the data file(s)." + }, + "port": { + "type": "integer", + "description": "Port to the server. No default value is assumed for custom servers." + }, + "project": { + "type": "string", + "description": "Project name." + }, + "region": { + "type": "string", + "description": "Cloud region." + }, + "regionName": { + "type": "string", + "description": "Region name." + }, + "schema": { + "type": "string", + "description": "Name of the schema." + }, + "serviceName": { + "type": "string", + "description": "Name of the service." + }, + "stagingDir": { + "type": "string", + "description": "Staging directory." + }, + "stream": { + "type": "string", + "description": "Name of the data stream." + }, + "topic": { + "type": "string", + "description": "Topic name." + }, + "warehouse": { + "type": "string", + "description": "Name of the cluster or warehouse." + } + } + }, "KafkaServer": { "type": "object", "title": "KafkaServer", From 65d2c9cfb02ad19608db59c0614cf2a345add3c4 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Wed, 2 Oct 2024 11:42:12 +0800 Subject: [PATCH 58/93] Update full example to use element for slaProperties --- docs/examples/all/full-example.odcs.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index efa90d6..ce41f11 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -167,7 +167,7 @@ slaProperties: - property: latency # Property, see list of values in DP QoS value: 4 unit: d # d, day, days for days; y, yr, years for years - column: tab1.txn_ref_dt # This would not be needed as it is the same table.column as the default one + element: tab1.txn_ref_dt # This would not be needed as it is the same table.column as the default one - property: generalAvailability value: "2022-05-12T09:30:10-08:00" - property: endOfSupport @@ -177,19 +177,19 @@ slaProperties: - property: retention value: 3 unit: y - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt - property: frequency value: 1 valueExt: 1 unit: d - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt - property: timeOfAvailability value: 09:00-08:00 - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt driver: regulatory # Describes the importance of the SLA: [regulatory|analytics|operational|...] - property: timeOfAvailability value: 08:00-08:00 - column: tab1.txn_ref_dt + element: tab1.txn_ref_dt driver: analytics # Tags From b65d511e89988a85b1796e2eb2eece6980c24412 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Wed, 2 Oct 2024 11:44:57 +0800 Subject: [PATCH 59/93] Copy v3.0.0 JSON schema to latest --- schema/odcs-json-schema-latest.json | 2375 ++++++++++++++++++++++++++- schema/odcs-json-schema-v3.0.0.json | 2 +- 2 files changed, 2375 insertions(+), 2 deletions(-) diff --git a/schema/odcs-json-schema-latest.json b/schema/odcs-json-schema-latest.json index 7097ad7..61e0a76 100644 --- a/schema/odcs-json-schema-latest.json +++ b/schema/odcs-json-schema-latest.json @@ -1 +1,2374 @@ -XXX REPLACE WITH FINAL v3.0.0 XXX +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "Open Data Contract Standard (ODCS)", + "description": "An open data contract specification to establish agreement between data producers and consumers.", + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "Current version of the data contract." + }, + "kind": { + "type": "string", + "default": "DataContract", + "description": "The kind of file this is. Valid value is `DataContract`.", + "enum": ["DataContract"] + }, + "apiVersion": { + "type": "string", + "default": "v3.0.0", + "description": "Version of the standard used to build data contract. Default value is v3.0.0.", + "enum": ["v3.0.0", "v2.2.2", "v2.2.1", "v2.2.0"] + }, + "id": { + "type": "string", + "description": "A unique identifier used to reduce the risk of dataset name collisions, such as a UUID." + }, + "name": { + "type": "string", + "description": "Name of the data contract." + }, + "type": { + "type": "string", + "description": "Identifies the types of objects in the dataset. For BigQuery or any other database, the expected value would be Tables.", + "examples": ["Tables"] + }, + "tenant": { + "type": "string", + "description": "Indicates the property the data is primarily associated with. Value is case insensitive." + }, + "tags": { + "$ref": "#/$defs/Tags" + }, + "status": { + "type": "string", + "description": "Current status of the dataset. Valid values are `production`, `test`, or `development`.", + "examples": ["production", "test", "development"] + }, + "servers": { + "type": "array", + "description": "List of servers where the datasets reside.", + "items": { + "$ref": "#/$defs/Server" + } + }, + "dataProduct": { + "type": "string", + "description": "The name of the data product." + }, + "description": { + "type": "object", + "description": "High level description of the dataset.", + "properties": { + "usage": { + "type": "string", + "description": "Intended usage of the dataset." + }, + "purpose": { + "type": "string", + "description": "Purpose of the dataset." + }, + "limitations": { + "type": "string", + "description": "Limitations of the dataset." + } + } + }, + "domain": { + "type": "string", + "description": "Name of the logical data domain.", + "examples": ["imdb_ds_aggregate", "receiver_profile_out", "transaction_profile_out"] + }, + "schema": { + "type": "array", + "description": "A list of elements within the schema to be cataloged.", + "items": { + "$ref": "#/$defs/SchemaObject" + } + }, + "support": { + "$ref": "#/$defs/Support" + }, + "price": { + "$ref": "#/$defs/Pricing" + }, + "team": { + "type": "array", + "items": { + "$ref": "#/$defs/Team" + } + }, + "roles": { + "type": "array", + "description": "A list of roles that will provide user access to the dataset.", + "items": { + "$ref": "#/$defs/Role" + } + }, + "slaDefaultElement": { + "type": "string", + "description": "Element (using the element path notation) to do the checks on." + }, + "slaProperties": { + "type": "array", + "description": "A list of key/value pairs for SLA specific properties. There is no limit on the type of properties (more details to come).", + "items": { + "$ref": "#/$defs/ServiceLevelAgreementProperty" + } + }, + "customProperties": { + "$ref": "#/$defs/CustomProperties" + }, + "contractCreatedTs": { + "type": "string", + "format": "date-time", + "description": "Timestamp in UTC of when the data contract was created." + } + }, + "required": ["version", "apiVersion", "kind", "id", "status"], + "additionalProperties": false, + "$defs": { + "Server": { + "type": "object", + "description": "Data source details of where data is physically stored.", + "properties": { + "server": { + "type": "string", + "description": "Identifier of the server." + }, + "type": { + "type": "string", + "description": "Type of the server.", + "enum": [ + "api", "athena", "azure", "bigquery", "clickhouse", "databricks", "denodo", "dremio", + "duckdb", "glue", "cloudsql", "db2", "informix", "kafka", "kinesis", "local", + "mysql", "oracle", "postgresql", "postgres", "presto", "pubsub", + "redshift", "s3", "sftp", "snowflake", "sqlserver", "synapse", "trino", "vertica", "custom" + ] + }, + "description": { + "type": "string", + "description": "Description of the server." + }, + "environment": { + "type": "string", + "description": "Environment of the server.", + "examples": ["prod", "preprod", "dev", "uat"] + }, + "roles": { + "type": "array", + "description": "List of roles that have access to the server.", + "items": { + "$ref": "#/$defs/Role" + } + }, + "customProperties": { + "$ref": "#/$defs/CustomProperties" + } + }, + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "api" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/ApiServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "athena" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/AthenaServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "azure" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/AzureServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "bigquery" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/BigQueryServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "clickhouse" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/ClickHouseServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "databricks" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/DatabricksServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "denodo" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/DenodoServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "dremio" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/DremioServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "duckdb" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/DuckdbServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "glue" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/GlueServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "cloudsql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/GoogleCloudSqlServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "db2" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/IBMDB2Server" + } + }, + { + "if": { + "properties": { + "type": { + "const": "informix" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/InformixServer" + } + }, + + { + "if": { + "properties": { + "type": { + "const": "custom" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/CustomServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "kafka" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/KafkaServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "kinesis" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/KinesisServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "local" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/LocalServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "mysql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/MySqlServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "oracle" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/OracleServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "postgresql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/PostgresServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "postgres" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/PostgresServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "presto" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/PrestoServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "pubsub" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/PubSubServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "redshift" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/RedshiftServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "s3" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/S3Server" + } + }, + { + "if": { + "properties": { + "type": { + "const": "sftp" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/SftpServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "snowflake" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/SnowflakeServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "sqlserver" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/SqlserverServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "synapse" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/SynapseServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "trino" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/TrinoServer" + } + }, + { + "if": { + "properties": { + "type": { + "const": "vertica" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/VerticaServer" + } + } + ], + "required": ["server", "type"] + }, + "ServerSource": { + "ApiServer": { + "type": "object", + "title": "AthenaServer", + "properties": { + "location": { + "type": "string", + "format": "uri", + "description": "The url to the API.", + "examples": [ + "https://api.example.com/v1" + ] + } + }, + "required": [ + "location" + ] + }, + "AthenaServer": { + "type": "object", + "title": "AthenaServer", + "properties": { + "stagingDir": { + "type": "string", + "format": "uri", + "description": "Amazon Athena automatically stores query results and metadata information for each query that runs in a query result location that you can specify in Amazon S3.", + "examples": [ + "s3://my_storage_account_name/my_container/path" + ] + }, + "schema": { + "type": "string", + "description": "Identify the schema in the data source in which your tables exist." + }, + "catalog": { + "type": "string", + "description": "Identify the name of the Data Source, also referred to as a Catalog.", + "default": "awsdatacatalog" + }, + "regionName": { + "type": "string", + "description": "The region your AWS account uses.", + "examples": ["eu-west-1"] + } + }, + "required": [ + "staging_dir", + "schema" + ] + }, + "AzureServer": { + "type": "object", + "title": "AzureServer", + "properties": { + "location": { + "type": "string", + "format": "uri", + "description": "Fully qualified path to Azure Blob Storage or Azure Data Lake Storage (ADLS), supports globs.", + "examples": [ + "az://my_storage_account_name.blob.core.windows.net/my_container/path/*.parquet", + "abfss://my_storage_account_name.dfs.core.windows.net/my_container_name/path/*.parquet" + ] + }, + "format": { + "type": "string", + "enum": [ + "parquet", + "delta", + "json", + "csv" + ], + "description": "File format." + }, + "delimiter": { + "type": "string", + "enum": [ + "new_line", + "array" + ], + "description": "Only for format = json. How multiple json documents are delimited within one file" + } + }, + "required": [ + "location", + "format" + ] + }, + "BigQueryServer": { + "type": "object", + "title": "BigQueryServer", + "properties": { + "project": { + "type": "string", + "description": "The GCP project name." + }, + "dataset": { + "type": "string", + "description": "The GCP dataset name." + } + }, + "required": [ + "project", + "dataset" + ] + }, + "ClickHouseServer": { + "type": "object", + "title": "ClickHouseServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the ClickHouse server." + }, + "port": { + "type": "integer", + "description": "The port to the ClickHouse server." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "port", + "database" + ] + }, + "DatabricksServer": { + "type": "object", + "title": "DatabricksServer", + "properties": { + "host": { + "type": "string", + "description": "The Databricks host", + "examples": [ + "dbc-abcdefgh-1234.cloud.databricks.com" + ] + }, + "catalog": { + "type": "string", + "description": "The name of the Hive or Unity catalog" + }, + "schema": { + "type": "string", + "description": "The schema name in the catalog" + } + }, + "required": [ + "catalog", + "schema" + ] + }, + "DenodoServer": { + "type": "object", + "title": "DenodoServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Denodo server." + }, + "port": { + "type": "integer", + "description": "The port of the Denodo server." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "port" + ] + }, + "DremioServer": { + "type": "object", + "title": "DremioServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Dremio server." + }, + "port": { + "type": "integer", + "description": "The port of the Dremio server." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + } + }, + "required": [ + "host", + "port" + ] + }, + "DuckdbServer": { + "type": "object", + "title": "DuckdbServer", + "properties": { + "database": { + "type": "string", + "description": "Path to duckdb database file." + }, + "schema": { + "type": "integer", + "description": "The name of the schema." + } + }, + "required": [ + "database" + ] + }, + "GlueServer": { + "type": "object", + "title": "GlueServer", + "properties": { + "account": { + "type": "string", + "description": "The AWS Glue account", + "examples": [ + "1234-5678-9012" + ] + }, + "database": { + "type": "string", + "description": "The AWS Glue database name", + "examples": [ + "my_database" + ] + }, + "location": { + "type": "string", + "format": "uri", + "description": "The AWS S3 path. Must be in the form of a URL.", + "examples": [ + "s3://datacontract-example-orders-latest/data/{model}" + ] + }, + "format": { + "type": "string", + "description": "The format of the files", + "examples": [ + "parquet", + "csv", + "json", + "delta" + ] + } + }, + "required": [ + "account", + "database" + ] + }, + "GoogleCloudSqlServer": { + "type": "object", + "title": "GoogleCloudSqlServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Google Cloud Sql server." + }, + "port": { + "type": "integer", + "description": "The port of the Google Cloud Sql server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + } + }, + "required": [ + "host", + "port", + "database", + "schema" + ] + }, + "IBMDB2Server": { + "type": "object", + "title": "IBMDB2Server", + "properties": { + "host": { + "type": "string", + "description": "The host of the IBM DB2 server." + }, + "port": { + "type": "integer", + "description": "The port of the IBM DB2 server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + } + }, + "required": [ + "host", + "port", + "database" + ] + }, + "InformixServer": { + "type": "object", + "title": "InformixServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the Informix server. " + }, + "port": { + "type": "integer", + "description": "The port to the Informix server. Defaults to 9088." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "database" + ] + }, + "CustomServer": { + "type": "object", + "title": "CustomServer", + "properties": { + "account": { + "type": "string", + "description": "Account used by the server." + }, + "catalog": { + "type": "string", + "description": "Name of the catalog." + }, + "database": { + "type": "string", + "description": "Name of the database." + }, + "dataset": { + "type": "string", + "description": "Name of the dataset." + }, + "delimiter": { + "type": "string", + "description": "Delimiter." + }, + "endpointUrl": { + "type": "string", + "description": "Server endpoint.", + "format": "uri" + }, + "format": { + "type": "string", + "description": "File format." + }, + "host": { + "type": "string", + "description": "Host name or IP address." + }, + "location": { + "type": "string", + "description": "A URL to a location.", + "format": "uri" + }, + "path": { + "type": "string", + "description": "Relative or absolute path to the data file(s)." + }, + "port": { + "type": "integer", + "description": "Port to the server. No default value is assumed for custom servers." + }, + "project": { + "type": "string", + "description": "Project name." + }, + "region": { + "type": "string", + "description": "Cloud region." + }, + "regionName": { + "type": "string", + "description": "Region name." + }, + "schema": { + "type": "string", + "description": "Name of the schema." + }, + "serviceName": { + "type": "string", + "description": "Name of the service." + }, + "stagingDir": { + "type": "string", + "description": "Staging directory." + }, + "stream": { + "type": "string", + "description": "Name of the data stream." + }, + "topic": { + "type": "string", + "description": "Topic name." + }, + "warehouse": { + "type": "string", + "description": "Name of the cluster or warehouse." + } + } + }, + "KafkaServer": { + "type": "object", + "title": "KafkaServer", + "description": "Kafka Server", + "properties": { + "host": { + "type": "string", + "description": "The bootstrap server of the kafka cluster." + }, + "topic": { + "type": "string", + "description": "The topic name." + }, + "format": { + "type": "string", + "description": "The format of the messages.", + "examples": ["json", "avro", "protobuf", "xml"], + "default": "json" + } + }, + "required": [ + "host", + "topic" + ] + }, + "KinesisServer": { + "type": "object", + "title": "KinesisDataStreamsServer", + "description": "Kinesis Data Streams Server", + "properties": { + "stream": { + "type": "string", + "description": "The name of the Kinesis data stream." + }, + "region": { + "type": "string", + "description": "AWS region.", + "examples": [ + "eu-west-1" + ] + }, + "format": { + "type": "string", + "description": "The format of the record", + "examples": [ + "json", + "avro", + "protobuf" + ] + } + }, + "required": [ + "stream" + ] + }, + "LocalServer": { + "type": "object", + "title": "LocalServer", + "properties": { + "path": { + "type": "string", + "description": "The relative or absolute path to the data file(s).", + "examples": [ + "./folder/data.parquet", + "./folder/*.parquet" + ] + }, + "format": { + "type": "string", + "description": "The format of the file(s)", + "examples": [ + "json", + "parquet", + "delta", + "csv" + ] + } + }, + "required": [ + "path", + "format" + ] + }, + "MySqlServer": { + "type": "object", + "title": "MySqlServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the MySql server." + }, + "port": { + "type": "integer", + "description": "The port of the MySql server." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "port", + "database" + ] + }, + "OracleServer": { + "type": "object", + "title": "OracleServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the oracle server", + "examples": [ + "localhost" + ] + }, + "port": { + "type": "integer", + "description": "The port to the oracle server.", + "examples": [ + 1523 + ] + }, + "serviceName": { + "type": "string", + "description": "The name of the service.", + "examples": [ + "service" + ] + } + }, + "required": [ + "host", + "port", + "serviceName" + ] + }, + "PostgresServer": { + "type": "object", + "title": "PostgresServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the Postgres server" + }, + "port": { + "type": "integer", + "description": "The port to the Postgres server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema in the database." + } + }, + "required": [ + "host", + "port", + "database", + "schema" + ] + }, + "PrestoServer": { + "type": "object", + "title": "PrestoServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the Presto server", + "examples": [ + "localhost:8080" + ] + }, + "catalog": { + "type": "string", + "description": "The name of the catalog.", + "examples": [ + "postgres" + ] + }, + "schema": { + "type": "string", + "description": "The name of the schema.", + "examples": [ + "public" + ] + } + }, + "required": [ + "host" + ] + }, + "PubSubServer": { + "type": "object", + "title": "PubSubServer", + "properties": { + "project": { + "type": "string", + "description": "The GCP project name." + }, + "topic": { + "type": "string", + "description": "The topic name." + } + }, + "required": [ + "project", + "topic" + ] + }, + "RedshiftServer": { + "type": "object", + "title": "RedshiftServer", + "properties": { + "host": { + "type": "string", + "description": "An optional string describing the server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + }, + "region": { + "type": "string", + "description": "AWS region of Redshift server.", + "examples": ["us-east-1"] + }, + "account": { + "type": "string", + "description": "The account used by the server." + } + }, + "required": [ + "database", + "schema" + ] + }, + "S3Server": { + "type": "object", + "title": "S3Server", + "properties": { + "location": { + "type": "string", + "format": "uri", + "description": "S3 URL, starting with `s3://`", + "examples": [ + "s3://datacontract-example-orders-latest/data/{model}/*.json" + ] + }, + "endpointUrl": { + "type": "string", + "format": "uri", + "description": "The server endpoint for S3-compatible servers.", + "examples": ["https://minio.example.com"] + }, + "format": { + "type": "string", + "enum": [ + "parquet", + "delta", + "json", + "csv" + ], + "description": "File format." + }, + "delimiter": { + "type": "string", + "enum": [ + "new_line", + "array" + ], + "description": "Only for format = json. How multiple json documents are delimited within one file" + } + }, + "required": [ + "location" + ] + }, + "SftpServer": { + "type": "object", + "title": "SftpServer", + "properties": { + "location": { + "type": "string", + "format": "uri", + "pattern": "^sftp://.*", + "description": "SFTP URL, starting with `sftp://`", + "examples": [ + "sftp://123.123.12.123/{model}/*.json" + ] + }, + "format": { + "type": "string", + "enum": [ + "parquet", + "delta", + "json", + "csv" + ], + "description": "File format." + }, + "delimiter": { + "type": "string", + "enum": [ + "new_line", + "array" + ], + "description": "Only for format = json. How multiple json documents are delimited within one file" + } + }, + "required": [ + "location" + ] + }, + "SnowflakeServer": { + "type": "object", + "title": "SnowflakeServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the Snowflake server" + }, + "port": { + "type": "integer", + "description": "The port to the Snowflake server." + }, + "account": { + "type": "string", + "description": "The Snowflake account used by the server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + }, + "warehouse": { + "type": "string", + "description": "The name of the cluster of resources that is a Snowflake virtual warehouse." + } + }, + "required": [ + "account", + "database", + "schema" + ] + }, + "SqlserverServer": { + "type": "object", + "title": "SqlserverServer", + "properties": { + "host": { + "type": "string", + "description": "The host to the database server", + "examples": [ + "localhost" + ] + }, + "port": { + "type": "integer", + "description": "The port to the database server.", + "default": 1433, + "examples": [ + 1433 + ] + }, + "database": { + "type": "string", + "description": "The name of the database.", + "examples": [ + "database" + ] + }, + "schema": { + "type": "string", + "description": "The name of the schema in the database.", + "examples": [ + "dbo" + ] + } + }, + "required": [ + "host", + "database", + "schema" + ] + }, + "SynapseServer": { + "type": "object", + "title": "SynapseServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Synapse server." + }, + "port": { + "type": "integer", + "description": "The port of the Synapse server." + }, + "database": { + "type": "string", + "description": "The name of the database." + } + }, + "required": [ + "host", + "port", + "database" + ] + }, + "TrinoServer": { + "type": "object", + "title": "TrinoServer", + "properties": { + "host": { + "type": "string", + "description": "The Trino host URL.", + "examples": [ + "localhost" + ] + }, + "port": { + "type": "integer", + "description": "The Trino port." + }, + "catalog": { + "type": "string", + "description": "The name of the catalog.", + "examples": [ + "hive" + ] + }, + "schema": { + "type": "string", + "description": "The name of the schema in the database.", + "examples": [ + "my_schema" + ] + } + }, + "required": [ + "host", + "port", + "catalog", + "schema" + ] + }, + "VerticaServer": { + "type": "object", + "title": "VerticaServer", + "properties": { + "host": { + "type": "string", + "description": "The host of the Vertica server." + }, + "port": { + "type": "integer", + "description": "The port of the Vertica server." + }, + "database": { + "type": "string", + "description": "The name of the database." + }, + "schema": { + "type": "string", + "description": "The name of the schema." + } + }, + "required": [ + "host", + "port", + "database", + "schema" + ] + } + }, + "SchemaElement": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the element." + }, + "physicalType": { + "type": "string", + "description": "The physical element data type in the data source.", + "examples": ["table", "view", "topic", "file"] + }, + "description": { + "type": "string", + "description": "Description of the element." + }, + "businessName": { + "type": "string", + "description": "The business name of the element." + }, + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "tags": { + "$ref": "#/$defs/Tags" + } + } + }, + "SchemaObject": { + "type": "object", + "properties": { + "logicalType": { + "type": "string", + "description": "The logical element data type.", + "enum": ["object"] + }, + "physicalName": { + "type": "string", + "description": "Physical name.", + "examples": ["table_1_2_0"] + }, + "dataGranularityDescription": { + "type": "string", + "description": "Granular level of the data in the object.", + "examples": ["Aggregation by country"] + }, + "properties": { + "type": "array", + "description": "A list of properties for the object.", + "items": { + "$ref": "#/$defs/SchemaProperty" + } + }, + "quality": { + "$ref": "#/$defs/DataQualityChecks" + } + }, + "allOf": [ + { + "$ref": "#/$defs/SchemaElement" + } + ], + "required": ["name"], + "unevaluatedProperties": false + }, + "SchemaBaseProperty": { + "type": "object", + "properties": { + "primaryKey": { + "type": "boolean", + "description": "Boolean value specifying whether the element is primary or not. Default is false." + }, + "primaryKeyPosition": { + "type": "integer", + "default": -1, + "description": "If element is a primary key, the position of the primary key element. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1." + }, + "logicalType": { + "type": "string", + "description": "The logical element data type.", + "enum": ["string", "date", "number", "integer", "object", "array", "boolean"] + }, + "logicalTypeOptions": { + "type": "object", + "description": "Additional optional metadata to describe the logical type." + }, + "physicalType": { + "type": "string", + "description": "The physical element data type in the data source. For example, VARCHAR(2), DOUBLE, INT." + }, + "required": { + "type": "boolean", + "default": false, + "description": "Indicates if the element may contain Null values; possible values are true and false. Default is false." + }, + "unique": { + "type": "boolean", + "default": false, + "description": "Indicates if the element contains unique values; possible values are true and false. Default is false." + }, + "partitioned": { + "type": "boolean", + "default": false, + "description": "Indicates if the element is partitioned; possible values are true and false." + }, + "partitionKeyPosition": { + "type": "integer", + "default": -1, + "description": "If element is used for partitioning, the position of the partition element. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1." + }, + "classification": { + "type": "string", + "description": "Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the element; expected values are 1, 2, 3, 4, or 5.", + "examples": ["confidential", "restricted", "public"] + }, + "encryptedName": { + "type": "string", + "description": "The element name within the dataset that contains the encrypted element value. For example, unencrypted element `email_address` might have an encryptedName of `email_address_encrypt`." + }, + "transformSourceObjects": { + "type": "array", + "description": "List of objects in the data source used in the transformation.", + "items": { + "type": "string" + } + }, + "transformLogic": { + "type": "string", + "description": "Logic used in the element transformation." + }, + "transformDescription": { + "type": "string", + "description": "Describes the transform logic in very simple terms." + }, + "examples": { + "type": "array", + "description": "List of sample element values.", + "items": { + "$ref": "#/$defs/AnyType" + } + }, + "criticalDataElement": { + "type": "boolean", + "default": false, + "description": "True or false indicator; If element is considered a critical data element (CDE) then true else false." + }, + "quality": { + "$ref": "#/$defs/DataQualityChecks" + } + }, + "allOf": [ + { + "$ref": "#/$defs/SchemaElement" + }, + { + "if": { + "properties": { + "logicalType": { + "const": "string" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { + "type": "object", + "properties": { + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length of the string." + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length of the string." + }, + "pattern": { + "type": "string", + "description": "Regular expression pattern to define valid value. Follows regular expression syntax from ECMA-262 (https://262.ecma-international.org/5.1/#sec-15.10.1)." + }, + "format": { + "type": "string", + "examples": ["password", "byte", "binary", "email", "uuid", "uri", "hostname", "ipv4", "ipv6"], + "description": "Provides extra context about what format the string follows." + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "date" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { + "type": "object", + "properties": { + "format": { + "type": "string", + "examples": ["yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "HH:mm:ss"], + "description": "Format of the date. Follows the format as prescribed by [JDK DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). For example, format 'yyyy-MM-dd'." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "maximum": { + "type": "string", + "description": "All date values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "minimum": { + "type": "string", + "description": "All date values are greater than or equal to this value (values >= minimum)." + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "anyOf": [ + { + "properties": { + "logicalType": { + "const": "integer" + } + } + } + ] + }, + "then": { + "properties": { + "logicalTypeOptions": { + "type": "object", + "properties": { + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0, + "description": "Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5." + }, + "maximum": { + "type": "number", + "description": "All values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "minimum": { + "type": "number", + "description": "All values are greater than or equal to this value (values >= minimum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "format": { + "type": "string", + "default": "i32", + "description": "Format of the value in terms of how many bits of space it can use and whether it is signed or unsigned (follows the Rust integer types).", + "enum": ["i8", "i16", "i32", "i64", "i128", "u8", "u16", "u32", "u64", "u128"] + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "anyOf": [ + { + "properties": { + "logicalType": { + "const": "number" + } + } + } + ] + }, + "then": { + "properties": { + "logicalTypeOptions": { + "type": "object", + "properties": { + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0, + "description": "Values must be multiples of this number. For example, multiple of 5 has valid values 0, 5, 10, -5." + }, + "maximum": { + "type": "number", + "description": "All values are less than or equal to this value (values <= maximum)." + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly less than the maximum value (values < maximum). Otherwise, less than or equal to the maximum value (values <= maximum)." + }, + "minimum": { + "type": "number", + "description": "All values are greater than or equal to this value (values >= minimum)." + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false, + "description": "If set to true, all values are strictly greater than the minimum value (values > minimum). Otherwise, greater than or equal to the minimum value (values >= minimum)." + }, + "format": { + "type": "string", + "default": "i32", + "description": "Format of the value in terms of how many bits of space it can use (follows the Rust float types).", + "enum": ["f32", "f64"] + } + }, + "additionalProperties": false + } + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "object" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { + "type": "object", + "properties": { + "maxProperties": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of properties." + }, + "minProperties": { + "type": "integer", + "minimum": 0, + "default": 0, + "description": "Minimum number of properties." + }, + "required": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "uniqueItems": true, + "description": "Property names that are required to exist in the object." + } + }, + "additionalProperties": false + }, + "properties": { + "type": "array", + "description": "A list of properties for the object.", + "items": { + "$ref": "#/$defs/SchemaProperty" + } + } + } + } + }, + { + "if": { + "properties": { + "logicalType": { + "const": "array" + } + } + }, + "then": { + "properties": { + "logicalTypeOptions": { + "type": "object", + "properties": { + "maxItems": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of items." + }, + "minItems": { + "type": "integer", + "minimum": 0, + "default": 0, + "description": "Minimum number of items" + }, + "uniqueItems": { + "type": "boolean", + "default": false, + "description": "If set to true, all items in the array are unique." + } + }, + "additionalProperties": false + }, + "items": { + "$ref": "#/$defs/SchemaItemProperty", + "description": "List of items in an array (only applicable when `logicalType: array`)." + } + } + } + } + ] + }, + "SchemaProperty": { + "type": "object", + "$ref": "#/$defs/SchemaBaseProperty", + "required": ["name"], + "unevaluatedProperties": false + }, + "SchemaItemProperty": { + "type": "object", + "$ref": "#/$defs/SchemaBaseProperty", + "properties": { + "properties": { + "type": "array", + "description": "A list of properties for the object.", + "items": { + "$ref": "#/$defs/SchemaProperty" + } + } + }, + "unevaluatedProperties": false + }, + "Tags": { + "type": "array", + "description": "A list of tags that may be assigned to the elements (object or property); the tags keyword may appear at any level.", + "items": { + "type": "string" + } + }, + "DataQuality": { + "type": "object", + "properties": { + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "businessImpact": { + "type": "string", + "description": "Consequences of the rule failure.", + "examples": ["operational", "regulatory"] + }, + "customProperties": { + "type": "array", + "description": "Additional properties required for rule execution.", + "items": { + "$ref": "#/$defs/CustomProperty" + } + }, + "description": { + "type": "string", + "description": "Describe the quality check to be completed." + }, + "dimension": { + "type": "string", + "description": "The key performance indicator (KPI) or dimension for data quality.", + "enum": ["accuracy", "completeness", "conformity", "consistency", "coverage", "timeliness", "uniqueness"] + }, + "method": { + "type": "string", + "examples": ["reconciliation"] + }, + "name": { + "type": "string", + "description": "Name of the data quality check." + }, + "schedule": { + "type": "string", + "description": "Rule execution schedule details.", + "examples": ["0 20 * * *"] + }, + "scheduler": { + "type": "string", + "description": "The name or type of scheduler used to start the data quality check.", + "examples": ["cron"] + }, + "severity": { + "type": "string", + "description": "The severance of the quality rule.", + "examples": ["info", "warning", "error"] + }, + "tags": { + "$ref": "#/$defs/Tags" + }, + "type": { + "type": "string", + "description": "The type of quality check. 'text' is human-readable text that describes the quality of the data. 'library' is a set of maintained predefined quality attributes such as row count or unique. 'sql' is an individual SQL query that returns a value that can be compared. 'custom' is quality attributes that are vendor-specific, such as Soda or Great Expectations.", + "enum": ["text", "library", "sql", "custom"], + "default": "library" + }, + "unit": { + "type": "string", + "description": "Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed.", + "examples": ["rows", "percent"] + } + }, + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "library" + } + } + }, + "then": { + "$ref": "#/$defs/DataQualityLibrary" + } + }, + { + "if": { + "properties": { + "type": { + "const": "sql" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/DataQualitySql" + } + }, + { + "if": { + "properties": { + "type": { + "const": "custom" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/DataQualityCustom" + } + } + ] + }, + "DataQualityChecks": { + "type": "array", + "description": "Data quality rules with all the relevant information for rule setup and execution.", + "items": { + "$ref": "#/$defs/DataQuality" + } + }, + "DataQualityLibrary": { + "type": "object", + "properties": { + "rule": { + "type": "string", + "description": "Define a data quality check based on the predefined rules as per ODCS.", + "examples": ["duplicateCount", "validValues", "rowCount"] + }, + "mustBe": { + "description": "Must be equal to the value to be valid. When using numbers, it is equivalent to '='." + }, + "mustNotBe": { + "description": "Must not be equal to the value to be valid. When using numbers, it is equivalent to '!='." + }, + "mustBeGreaterThan": { + "type": "number", + "description": "Must be greater than the value to be valid. It is equivalent to '>'." + }, + "mustBeGreaterOrEqualTo": { + "type": "number", + "description": "Must be greater than or equal to the value to be valid. It is equivalent to '>='." + }, + "mustBeLessThan": { + "type": "number", + "description": "Must be less than the value to be valid. It is equivalent to '<'." + }, + "mustBeLessOrEqualTo": { + "type": "number", + "description": "Must be less than or equal to the value to be valid. It is equivalent to '<='." + }, + "mustBeBetween": { + "type": "array", + "description": "Must be between the two numbers to be valid. Smallest number first in the array.", + "minItems": 2, + "maxItems": 2, + "uniqueItems": true, + "items": { + "type": "number" + } + }, + "mustNotBeBetween": { + "type": "array", + "description": "Must not be between the two numbers to be valid. Smallest number first in the array.", + "minItems": 2, + "maxItems": 2, + "uniqueItems": true, + "items": { + "type": "number" + } + } + }, + "required": ["rule"] + }, + "DataQualitySql": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Query string that adheres to the dialect of the provided server.", + "examples": ["SELECT COUNT(*) FROM ${table} WHERE ${column} IS NOT NULL"] + } + }, + "required": ["query"] + }, + "DataQualityCustom": { + "type": "object", + "properties": { + "engine": { + "type": "string", + "description": "Name of the engine which executes the data quality checks.", + "examples": ["soda", "great-expectations", "monte-carlo", "dbt"] + }, + "implementation": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "required": ["engine", "implementation"] + }, + "AuthoritativeDefinitions": { + "type": "array", + "description": "List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "URL to the authority." + }, + "type": { + "type": "string", + "description": "Type of definition for authority: v2.3 adds standard values: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`.", + "examples": ["businessDefinition", "transformationImplementation", "videoTutorial", "tutorial", "implementation"] + } + }, + "required": ["url", "type"] + } + }, + "Support": { + "type": "array", + "description": "Top level for support channels.", + "items": { + "$ref": "#/$defs/SupportItem" + } + }, + "SupportItem": { + "type": "object", + "properties": { + "channel": { + "type": "string", + "description": "Channel name or identifier." + }, + "url": { + "type": "string", + "description": "Access URL using normal [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax) (https, mailto, etc.)." + }, + "description": { + "type": "string", + "description": "Description of the channel, free text." + }, + "tool": { + "type": "string", + "description": "Name of the tool, value can be `email`, `slack`, `teams`, `discord`, `ticket`, or `other`.", + "examples": ["email", "slack", "teams", "discord", "ticket", "other"] + }, + "scope": { + "type": "string", + "description": "Scope can be: `interactive`, `announcements`, `issues`.", + "examples": ["interactive", "announcements", "issues"] + }, + "invitationUrl": { + "type": "string", + "description": "Some tools uses invitation URL for requesting or subscribing. Follows the [URL scheme](https://en.wikipedia.org/wiki/URL#Syntax)." + } + }, + "required": ["channel", "url"] + }, + "Pricing": { + "type": "object", + "properties": { + "priceAmount": { + "type": "number", + "description": "Subscription price per unit of measure in `priceUnit`." + }, + "priceCurrency": { + "type": "string", + "description": "Currency of the subscription price in `price.priceAmount`." + }, + "priceUnit": { + "type": "string", + "description": "The unit of measure for calculating cost. Examples megabyte, gigabyte." + } + } + }, + "Team": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The team's username or email." + }, + "role": { + "type": "string", + "description": "The team's job role; Examples might be owner, data steward. There is no limit on the role." + }, + "dateIn": { + "type": "string", + "format": "date", + "description": "The date when the user became a team." + }, + "dateOut": { + "type": "string", + "format": "date", + "description": "The date when the user ceased to be a team" + }, + "replacedByUsername": { + "type": "string", + "description": "The username of the user who replaced the team" + } + } + }, + "Role": { + "type": "object", + "properties": { + "role": { + "type": "string", + "description": "Name of the IAM role that provides access to the dataset." + }, + "description": { + "type": "string", + "description": "Description of the IAM role and its permissions." + }, + "access": { + "type": "string", + "description": "The type of access provided by the IAM role." + }, + "firstLevelApprovers": { + "type": "string", + "description": "The name(s) of the first-level approver(s) of the role." + }, + "secondLevelApprovers": { + "type": "string", + "description": "The name(s) of the second-level approver(s) of the role." + } + }, + "required": ["role"] + }, + "ServiceLevelAgreementProperty": { + "type": "object", + "properties": { + "property": { + "type": "string", + "description": "Specific property in SLA, check the periodic table. May requires units (more details to come)." + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "integer" + }, + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Agreement value. The label will change based on the property itself." + }, + "valueExt": { + "$ref": "#/$defs/AnyNonCollectionType", + "description": "Extended agreement value. The label will change based on the property itself." + }, + "unit": { + "type": "string", + "description": "**d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard." + }, + "element": { + "type": "string", + "description": "Element(s) to check on. Multiple elements should be extremely rare and, if so, separated by commas." + }, + "driver": { + "type": "string", + "description": "Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`.", + "examples": ["regulatory", "analytics", "operational"] + } + }, + "required": ["property", "value"] + }, + "CustomProperties": { + "type": "array", + "description": "A list of key/value pairs for custom properties.", + "items": { + "$ref": "#/$defs/CustomProperty" + } + }, + "CustomProperty": { + "type": "object", + "properties": { + "property": { + "type": "string", + "description": "The name of the key. Names should be in camel case–the same as if they were permanent properties in the contract." + }, + "value": { + "$ref": "#/$defs/AnyType", + "description": "The value of the key." + } + } + }, + "AnyType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "integer" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array" + }, + { + "type": "object" + } + ] + }, + "AnyNonCollectionType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "integer" + }, + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + } +} diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index e8f2876..61e0a76 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2019-09/schema", - "title": "Open Data Contract Standard (OCDS)", + "title": "Open Data Contract Standard (ODCS)", "description": "An open data contract specification to establish agreement between data producers and consumers.", "type": "object", "properties": { From 2ac7100b97e90e7d02b4662fc10a634151b0ba2c Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 08:49:37 -0400 Subject: [PATCH 60/93] Update based on PR feedback --- CHANGELOG.md | 4 ++-- docs/examples/all/full-example.odcs.yaml | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bae7f68..be57d98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,8 +50,8 @@ This document tracks the history and evolution of the **Open Data Contract Stand * `criticalDataElementStatus` is now `criticalDataElement`. * `clusterKeyPosition` is not supported anymore, if needed, consider a custom property. * `transformSourceTables` is now `transformSourceObjects` - * Restrict `dataset.table.columns.column.logicalType` to be one of `string`, `date`, `number`, `integer`, `object`, `array`, `boolean`. - * Add `dataset.table.columns.column.logicalTypeOptions`. + * Restrict `schema.*.logicalType` to be one of `string`, `date`, `number`, `integer`, `object`, `array`, `boolean`. + * Add `schema.*.logicalTypeOptions`. * **Changes** to Data Quality: * Significant changes have been applied to support more tools and use cases. Please review the new section. * If needed, `templateName` is a custom property. diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index ce41f11..3f95c69 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -192,6 +192,18 @@ slaProperties: element: tab1.txn_ref_dt driver: analytics +# Support +support: + - channel: #product-help Simple Slack communication channel + tool: slack + url: https://aidaug.slack.com/archives/C05UZRSBKLY + - channel: datacontract-ann # Simple distribution list + tool: email + url: mailto:datacontract-ann@bitol.io + - channel: Feedback # Product Feedback + description: General Product Feedback (Public) + url: https://product-feedback.com + # Tags tags: - transactions From 38ad256cd46f529eeab5cf032b6224dfae3cfe28 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 08:52:45 -0400 Subject: [PATCH 61/93] Update signed-off-by: Jean-Georges Perrin (jgp@mycompanyname.com) --- CHANGELOG.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be57d98..75c5c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color This document tracks the history and evolution of the **Open Data Contract Standard**. -# v3.0.0 - 2024-xx-xx - IN PROGRESS +# v3.0.0 - 2024-10-05 - IN REVIEW * **New section**: Support & communication channels. * **Changes** to fundamentals : @@ -88,7 +88,8 @@ This document tracks the history and evolution of the **Open Data Contract Stand * Add in mkdocs for creating a [documentation website](https://bitol-io.github.io/open-data-contract-standard/). Check [building-doc.md](building-doc.md). * Add vendors page [vendors.md](vendors.md). Feel free to add anyone there. -# v2.2.1 - 2023-12-18 - APPROVED + +# v2.2.1 - 2023-12-18 - REPLACED BY V2.2.2 * Reformat quality examples to be valid YAML. * Type of definition for authority have standard values: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`. @@ -97,7 +98,8 @@ This document tracks the history and evolution of the **Open Data Contract Stand * Integrated as part of [Bitol](https://lfaidata.foundation/projects/bitol/). * Reformat Markdown tables. -# v2.2.0 - 2023-07-27 - APPROVED + +# v2.2.0 - 2023-07-27 - REPLACED BY V2.2.1 * New name to Open Data Contract Standard. * `templateName` is now called `standardVersion`, v2.2.0 parsers should account for this change and support both to avoid a breaking change. @@ -106,12 +108,14 @@ This document tracks the history and evolution of the **Open Data Contract Stand * Various improvements and typo corrections. * Finalization of fork under AIDA User Group. -# v2.1.1 - 2023-04-26 - APPROVED + +# v2.1.1 - 2023-04-26 - REPLACED BY V2.2.0 * Open source version. * Additional value field `valueExt` in SLA. -# v2.1.0 - 2023-03-23 - APPROVED + +# v2.1.0 - 2023-03-23 - REPLACED BY V2.1.1 ## Data Quality The data contract adds elements specifically for interfacing with the Data Quality tooling. @@ -137,7 +141,7 @@ The service-level agreements not previously used are more detailed to follow the ## Other Removed the weight for system ratings from the data contract. Their default values remain. -# v2.0.0 - SUPERSEED BY V2.1.0 +# v2.0.0 - REPLACED BY V2.1.0 ## Guidelines & Evolution * [Type case](https://google.github.io/styleguide/jsoncstyleguide.xml?showone=Property_Name_Format#Property_Name_Format) From fe9e96e8dd6b86d8cfefa49e65c668b103f52e58 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 10:13:29 -0400 Subject: [PATCH 62/93] Update full-example.odcs.yaml signed-off: jgp --- docs/examples/all/full-example.odcs.yaml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index 3f95c69..3747f5d 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -192,17 +192,7 @@ slaProperties: element: tab1.txn_ref_dt driver: analytics -# Support -support: - - channel: #product-help Simple Slack communication channel - tool: slack - url: https://aidaug.slack.com/archives/C05UZRSBKLY - - channel: datacontract-ann # Simple distribution list - tool: email - url: mailto:datacontract-ann@bitol.io - - channel: Feedback # Product Feedback - description: General Product Feedback (Public) - url: https://product-feedback.com + # Tags tags: From c767b8f310556f9f892c4003b3bb7c85e0ba9b34 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 10:18:39 -0400 Subject: [PATCH 63/93] Typo in name signed-off: Jean-Georges "jgp" Perrin dev@jgp.net Co-Authored-By: Diego Carvallo <5825465+dccakes@users.noreply.github.com> --- docs/examples/all/full-example.odcs.yaml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index 3747f5d..a574844 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -192,7 +192,17 @@ slaProperties: element: tab1.txn_ref_dt driver: analytics - +# Support +support: + - channel: '#product-help' # Simple Slack communication channel + tool: slack + url: https://aidaug.slack.com/archives/C05UZRSBKLY + - channel: datacontract-ann # Simple distribution list + tool: email + url: mailto:datacontract-ann@bitol.io + - channel: Feedback # Product Feedback + description: General Product Feedback (Public) + url: https://product-feedback.com # Tags tags: From ef392fd02e1c37e966c76f90a1f6b98c811a8e1c Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 10:21:41 -0400 Subject: [PATCH 64/93] Update full-example.odcs.yaml Signed-off-by: Jean-Georges "jgp" Perrin Co-Authored-By: Diego Carvallo <5825465+dccakes@users.noreply.github.com> --- docs/examples/all/full-example.odcs.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index a574844..4a2e379 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -13,10 +13,11 @@ description: tenant: ClimateQuantumInc kind: DataContract -apiVersion: v3.0.0 # Standard version (follows semantic versioning, previously known as templateVersion) +apiVersion: v3.0.0 # Standard version (follows semantic versioning) type: tables +# Infrastructure & servers servers: - server: my-postgres type: postgres @@ -121,12 +122,14 @@ schema: schedule: 0 20 * * * scheduler: cron + # Pricing price: priceAmount: 9.95 priceCurrency: USD priceUnit: megabyte + # Team team: - username: ceastwood @@ -142,6 +145,7 @@ team: comment: Keeper of the grail dateIn: "2022-10-01" + # Roles roles: - role: microstrategy_user_opr @@ -192,6 +196,7 @@ slaProperties: element: tab1.txn_ref_dt driver: analytics + # Support support: - channel: '#product-help' # Simple Slack communication channel @@ -204,10 +209,12 @@ support: description: General Product Feedback (Public) url: https://product-feedback.com + # Tags tags: - transactions + # Custom properties customProperties: - property: refRulesetName From 9f5305ee84d4315f677700fa77e6d7af2332f241 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 10:24:01 -0400 Subject: [PATCH 65/93] Update full-example.odcs.yaml Signed-off-by: Jean-Georges "jgp" Perrin dev@jgp.net Co-Authored-By: Diego Carvallo <5825465+dccakes@users.noreply.github.com> --- docs/examples/all/full-example.odcs.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index 4a2e379..66e7b13 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -202,12 +202,7 @@ support: - channel: '#product-help' # Simple Slack communication channel tool: slack url: https://aidaug.slack.com/archives/C05UZRSBKLY - - channel: datacontract-ann # Simple distribution list - tool: email - url: mailto:datacontract-ann@bitol.io - - channel: Feedback # Product Feedback - description: General Product Feedback (Public) - url: https://product-feedback.com + # Tags From b92cbf3655961f88d53c7e3f705d02c21575986d Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 10:26:25 -0400 Subject: [PATCH 66/93] Update full-example.odcs.yaml Signed-off-by: Jean-Georges "jgp" Perrin --- docs/examples/all/full-example.odcs.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index 66e7b13..e049ba8 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -202,7 +202,9 @@ support: - channel: '#product-help' # Simple Slack communication channel tool: slack url: https://aidaug.slack.com/archives/C05UZRSBKLY - + - channel: datacontract-ann # Simple distribution list + tool: email + url: mailto:datacontract-ann@bitol.io # Tags From c7b1ce52eb49225f5597d176edecaa96f459ead0 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 10:27:37 -0400 Subject: [PATCH 67/93] Debugging Signed-off-by: Jean-Georges "jgp" Perrin --- docs/examples/all/full-example.odcs.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index e049ba8..87fb76f 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -205,7 +205,9 @@ support: - channel: datacontract-ann # Simple distribution list tool: email url: mailto:datacontract-ann@bitol.io - + - channel: Feedback # Product Feedback + description: General Product Feedback (Public) + url: https://product-feedback.com # Tags tags: From 3461d18f2933e063e9732c9d8277f8f4e75f5d97 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 10:28:43 -0400 Subject: [PATCH 68/93] Debugging more Signed-off-by: Jean-Georges "jgp" Perrin dev@jgp.net --- docs/examples/all/full-example.odcs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index 87fb76f..6ea6a12 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -205,7 +205,7 @@ support: - channel: datacontract-ann # Simple distribution list tool: email url: mailto:datacontract-ann@bitol.io - - channel: Feedback # Product Feedback + - channel: Feedback # Product Feedback description: General Product Feedback (Public) url: https://product-feedback.com From cde738ce0bb5e5a37063ab0084dd4d73933f64fb Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Wed, 2 Oct 2024 10:37:13 -0400 Subject: [PATCH 69/93] Reintroduced schema v2.2.1 --- schema/odcs-json-schema-v2.2.1.json | 523 ++++++++++++++++++++++++++++ 1 file changed, 523 insertions(+) create mode 100644 schema/odcs-json-schema-v2.2.1.json diff --git a/schema/odcs-json-schema-v2.2.1.json b/schema/odcs-json-schema-v2.2.1.json new file mode 100644 index 0000000..0c01006 --- /dev/null +++ b/schema/odcs-json-schema-v2.2.1.json @@ -0,0 +1,523 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "Open Data Contract Standard (OCDS)", + "description": "An open data contract specification to establish agreement between data producers and consumers.", + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "Current version of the data contract." + }, + "kind": { + "type": "string", + "default": "DataContract", + "description": "The kind of file this is. Valid value is `DataContract`.", + "enum": ["DataContract"] + }, + "apiVersion": { + "type": "string", + "default": "v2.3.0", + "description": "Version of the standard used to build data contract. Default value is v2.3.0.", + "pattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+" + }, + "uuid": { + "type": "string", + "description": "A unique identifier used to reduce the risk of dataset name collisions; initially the UUID will be created using a UUID generator tool ([example](https://www.uuidgenerator.net/)). However, we may want to develop a method that accepts a seed value using a combination of fields–such as name, kind and source–to create a repeatable value." + }, + "datasetKind": { + "type": "string", + "description": "The kind of dataset being cataloged; Expected values are `virtualDataset` or `managedDataset`.", + "examples": ["virtualDataset", "managedDataset"] + }, + "userConsumptionMode": { + "type": "string", + "description": "List of data modes for which the dataset may be used. Expected sample values might be `analytical` or `operational`.
Note: in the future, this will probably be replaced by ports.", + "examples": ["analytical", "operational"] + }, + "type": { + "type": "string", + "description": "Identifies the types of objects in the dataset. For BigQuery or any other database, the expected value would be Tables.", + "examples": ["Tables"] + }, + "tenant": { + "type": "string", + "description": "Indicates the property the data is primarily associated with. Value is case insensitive." + }, + "tags": { + "type": "array", + "description": "A list of tags that may be assigned to the dataset, table or column; the `tags` keyword may appear at any level.", + "items": { + "type": "string" + } + }, + "status": { + "type": "string", + "description": "Current status of the dataset. Valid values are `production`, `test`, or `development`.", + "examples": ["production", "test", "development"] + }, + "sourceSystem": { + "type": "string", + "description": "The system where the dataset resides. Expected value can be BigQuery.", + "examples": ["BigQuery"] + }, + "sourcePlatform": { + "type": "string", + "description": "The platform where the dataset resides. Expected value is GoogleCloudPlatform, IBMCloud, Azure...", + "examples": ["GoogleCloudPlatform", "IBMCloud", "Azure", "AWS"] + }, + "server": { + "type": "string", + "description": "The server where the dataset resides." + }, + "quantumName": { + "type": "string", + "description": "The name of the data quantum or data product." + }, + "productSlackChannel": { + "type": "string", + "description": "Slack channel of the team responsible for maintaining the dataset." + }, + "productFeedbackUrl": { + "type": "string", + "description": "The URL for submitting feedback to the team responsible for maintaining the dataset." + }, + "productDl": { + "type": "string", + "description": "The email distribution list (DL) of the persons or team responsible for maintaining the dataset." + }, + "username": { + "type": "string", + "description": "User credentials for connecting to the dataset; how the credentials will be stored/passed is outside of the scope of the contract." + }, + "password": { + "type": "string", + "description": "User credentials for connecting to the dataset; how the credentials will be stored/passed is out of the scope of this contract." + }, + "driverVersion": { + "type": "string", + "description": "The version of the connection driver to be used to connect to the dataset." + }, + "driver": { + "type": "string", + "description": "The connection driver required to connect to the dataset." + }, + "description": { + "type": "object", + "description": "High level description of the dataset.", + "properties": { + "usage": { + "type": "string", + "description": "Intended usage of the dataset." + }, + "purpose": { + "type": "string", + "description": "Purpose of the dataset." + }, + "limitations": { + "type": "string", + "description": "Limitations of the dataset." + } + } + }, + "project": { + "type": "string", + "description": "Associated project name, can be used for billing or administrative purpose. Used to be datasetProject." + }, + "datasetName": { + "type": "string", + "description": "May be required in cloud instance like GCP BigQuery dataset name." + }, + "datasetDomain": { + "type": "string", + "description": "Name of the logical domain dataset the contract describes. This field is only required for output data contracts.", + "examples": ["imdb_ds_aggregate", "receiver_profile_out", "transaction_profile_out"] + }, + "database": { + "type": "string", + "description": "The database where the dataset resides." + }, + "dataset": { + "type": "array", + "items": { + "$ref": "#/$defs/Dataset" + } + }, + "price": { + "$ref": "#/$defs/Pricing" + }, + "stakeholders": { + "type": "array", + "items": { + "$ref": "#/$defs/Stakeholder" + } + }, + "roles": { + "type": "array", + "description": "A list of roles that will provide user access to the dataset.", + "items": { + "$ref": "#/$defs/Role" + } + }, + "slaDefaultColumn": { + "type": "string", + "description": "Columns (using the Table.Column notation) to do the checks on. By default, it is the partition column." + }, + "slaProperties": { + "type": "array", + "description": "A list of key/value pairs for SLA specific properties. There is no limit on the type of properties (more details to come).", + "items": { + "$ref": "#/$defs/ServiceLevelAgreementProperty" + } + } + }, + "required": ["version", "kind", "uuid", "type", "status", "dataset", "datasetName", "quantumName"], + "$defs": { + "Dataset": { + "type": "object", + "properties": { + "table": { + "type": "string", + "description": "Name of the table being cataloged; the value should only contain the table name. Do not include the project or dataset name in the value." + }, + "physicalName": { + "type": "string", + "description": "Physical name of the table, default value is table name + version separated by underscores, as `table_1_2_0`.", + "examples": ["table_1_2_0"] + }, + "priorTableName": { + "type": "string", + "description": "Name of the previous version of the dataset, if applicable." + }, + "description": { + "type": "array", + "description": "List of links to sources that provide more detail on column logic or values; examples would be URL to a GitHub repo, Collibra, on another tool.", + "items": { + "type": "string" + } + }, + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "dataGranularity": { + "type": "string", + "description": "Granular level of the data in the table. Example would be `pmt_txn_id`.", + "examples": ["pmt_txn_id"] + }, + "columns": { + "type": "array", + "description": "Array. A list of columns in the table.", + "items": { + "$ref": "#/$defs/Column" + } + }, + "quality": { + "type": "array", + "description": "Data quality rules with all the relevant information for rule setup and execution.", + "items": { + "$ref": "#/$defs/DataQuality" + } + } + }, + "required": ["table"] + }, + "Column": { + "type": "object", + "properties": { + "column": { + "type": "string", + "description": "The name of the column." + }, + "isPrimaryKey": { + "type": "string", + "description": "Boolean value specifying whether the column is primary or not. Default is false." + }, + "primaryKeyPosition": { + "type": "integer", + "default": -1, + "description": "If column is a primary key, the position of the primary key column. Starts from 1. Example of `account_id, name` being primary key columns, `account_id` has primaryKeyPosition 1 and `name` primaryKeyPosition 2. Default to -1." + }, + "businessName": { + "type": "string", + "description": "The business name of the column." + }, + "logicalType": { + "type": "string", + "description": "The logical column datatype." + }, + "physicalType": { + "type": "string", + "description": "The physical column datatype." + }, + "description": { + "type": "string", + "description": "Description of the column." + }, + "isNullable": { + "type": "boolean", + "default": false, + "description": "Indicates if the column may contain Null values; possible values are true and false. Default is false." + }, + "isUnique": { + "type": "boolean", + "default": false, + "description": "Indicates if the column contains unique values; possible values are true and false. Default is false." + }, + "partitionStatus": { + "type": "boolean", + "default": false, + "description": "Indicates if the column is partitioned; possible values are true and false." + }, + "partitionKeyPosition": { + "type": "integer", + "default": -1, + "description": "If column is used for partitioning, the position of the partition column. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1." + }, + "clusterStatus": { + "type": "boolean", + "default": false, + "description": "Indicates of the column is clustered; possible values are true and false." + }, + "clusterKeyPosition": { + "type": "integer", + "default": -1, + "description": "If column is used for clustering, the position of the cluster column. Starts from 1. Example of `year, date` being cluster columns, `year` has clusterKeyPosition 1 and `date` clusterKeyPosition 2. Default to -1." + }, + "classification": { + "type": "string", + "description": "Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5.", + "examples": ["confidential", "restricted", "public"] + }, + "authoritativeDefinitions": { + "$ref": "#/$defs/AuthoritativeDefinitions" + }, + "encryptedColumnName": { + "type": "string", + "description": "The column name within the table that contains the encrypted column value. For example, unencrypted column `email_address` might have an encryptedColumnName of `email_address_encrypt`." + }, + "transformSourceTables": { + "type": "array", + "description": "List of sources used in column transformation.", + "items": { + "type": "string" + } + }, + "transformLogic": { + "type": "string", + "description": "Logic used in the column transformation." + }, + "transformDescription": { + "type": "string", + "description": "Describes the transform logic in very simple terms." + }, + "sampleValues": { + "type": "array", + "description": "List of sample column values.", + "items": { + "type": "string" + } + }, + "criticalDataElementStatus": { + "type": "boolean", + "default": false, + "description": "True or false indicator; If element is considered a critical data element (CDE) then true else false." + }, + "tags": { + "type": "array", + "description": "A list of tags that may be assigned to the dataset, table or column; the tags keyword may appear at any level.", + "items": { + "type": "string" + } + } + }, + "required": ["column", "logicalType", "physicalType"] + }, + "DataQuality": { + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "The Rosewall data quality code(s) indicating which quality checks need to be performed at the dataset, table or column level; The quality keyword may appear at any level; Some quality checks require parameters such so the check can be completed (eg, list of fields used to identify a distinct row) therefore some quality checks may be followed by a single value or an array; See appendix for link to quality checks." + }, + "templateName": { + "type": "string", + "description": "The template name which indicates what is the equivalent template from the tool." + }, + "description": { + "type": "string", + "description": "Describe the quality check to be completed." + }, + "toolName": { + "type": "string", + "description": "Name of the tool used to complete the quality check; Most will be Elevate initially." + }, + "toolRuleName": { + "type": "string", + "description": "Name of the quality tool's rule created to complete the quality check." + }, + "dimension": { + "type": "string", + "description": "The key performance indicator (KPI) or dimension for data quality." + }, + "columns": { + "type": "string", + "description": "List of columns to be used in the quality check." + }, + "column": { + "type": "string", + "description": "To be used in lieu of quality.columns when only a single column is required for the quality check." + }, + "type": { + "type": "string", + "description": "The type of quality check." + }, + "severity": { + "type": "string", + "description": "The severance of the quality rule." + }, + "businessImpact": { + "type": "string", + "description": "Consequences of the rule failure." + }, + "scheduleCronExpression": { + "type": "string", + "description": "Rule execution schedule details." + }, + "customProperties": { + "type": "array", + "description": "Additional properties required for rule execution.", + "items": { + "$ref": "#/$defs/CustomProperty" + } + } + }, + "required": ["templateName", "toolName"] + }, + "AuthoritativeDefinitions": { + "type": "array", + "description": "List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "URL to the authority." + }, + "type": { + "type": "string", + "description": "Type of definition for authority: v2.3 adds standard values: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`.", + "examples": ["businessDefinition", "transformationImplementation", "videoTutorial", "tutorial", "implementation"] + } + }, + "required": ["url", "type"] + } + }, + "Pricing": { + "type": "object", + "properties": { + "priceAmount": { + "type": "string", + "description": "Subscription price per unit of measure in `priceUnit`." + }, + "priceCurrency": { + "type": "string", + "description": "Currency of the subscription price in `price.priceAmount`." + }, + "priceUnit": { + "type": "string", + "description": "The unit of measure for calculating cost. Examples megabyte, gigabyte." + } + } + }, + "Stakeholder": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The stakeholder's username or email." + }, + "role": { + "type": "string", + "description": "The stakeholder's job role; Examples might be owner, data steward. There is no limit on the role." + }, + "dateIn": { + "type": "string", + "description": "The date when the user became a stakeholder." + }, + "dateOut": { + "type": "string", + "description": "The date when the user ceased to be a stakeholder" + }, + "replacedByUsername": { + "type": "string", + "description": "The username of the user who replaced the stakeholder" + } + } + }, + "Role": { + "type": "object", + "properties": { + "role": { + "type": "string", + "description": "Name of the IAM role that provides access to the dataset; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + }, + "access": { + "type": "string", + "description": "The type of access provided by the IAM role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + }, + "firstLevelApprovers": { + "type": "string", + "description": "The name(s) of the first level approver(s) of the role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + }, + "secondLevelApprovers": { + "type": "string", + "description": "The name(s) of the second level approver(s) of the role; the value will generally come directly from the \"BQ dataset to IAM roles mapping\" document." + } + }, + "required": ["role", "access"] + }, + "ServiceLevelAgreementProperty": { + "type": "object", + "properties": { + "property": { + "type": "string", + "description": "Specific property in SLA, check the periodic table. May requires units (more details to come)." + }, + "value": { + "type": "string", + "description": "Agreement value. The label will change based on the property itself." + }, + "valueExt": { + "type": "string", + "description": "Extended agreement value. The label will change based on the property itself." + }, + "unit": { + "type": "string", + "description": "**d**, day, days for days; **y**, yr, years for years, etc. Units use the ISO standard." + }, + "column": { + "type": "string", + "description": "Column(s) to check on. Multiple columns should be extremely rare and, if so, separated by commas." + }, + "driver": { + "type": "string", + "description": "Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`.", + "examples": ["regulatory", "analytics", "operational"] + } + }, + "required": ["property", "value"] + }, + "CustomProperty": { + "type": "object", + "properties": { + "property": { + "type": "string", + "description": "The name of the key. Names should be in camel case–the same as if they were permanent properties in the contract." + }, + "value": { + "type": "object", + "description": "The value of the key." + } + } + } + } +} \ No newline at end of file From c63ac4f27ca03866334feca3a5a0fa44bc7c3b25 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Thu, 3 Oct 2024 19:00:45 +0800 Subject: [PATCH 70/93] ODCS-36: Move scripts under src/script folder --- .github/workflows/docs-site-deploy.yaml | 8 ++------ .github/workflows/validate-examples.yaml | 2 +- script/README.md | 9 --------- src/script/README.md | 9 +++++++++ {script => src/script}/build_docs.sh | 0 {script => src/script}/generate-server-types.ruby | 0 {script => src/script}/validate-examples.sh | 4 ++-- 7 files changed, 14 insertions(+), 18 deletions(-) delete mode 100644 script/README.md create mode 100644 src/script/README.md rename {script => src/script}/build_docs.sh (100%) rename {script => src/script}/generate-server-types.ruby (100%) rename {script => src/script}/validate-examples.sh (85%) diff --git a/.github/workflows/docs-site-deploy.yaml b/.github/workflows/docs-site-deploy.yaml index 8aa8578..efeccd6 100644 --- a/.github/workflows/docs-site-deploy.yaml +++ b/.github/workflows/docs-site-deploy.yaml @@ -10,8 +10,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: Configure Git Credentials run: | git config user.name github-actions[bot] @@ -26,10 +24,8 @@ jobs: path: .cache restore-keys: | mkdocs-material- - - run: pip install mkdocs-open-in-new-tab mike - - run: pip install mkdocs-material - - run: pip install "mkdocs-material[imaging]" - - run: bash script/build_docs.sh + - run: pip install mkdocs-material mkdocs-open-in-new-tab "mkdocs-material[imaging]" mike + - run: bash src/script/build_docs.sh - run: | latest_tag=$(git describe --tags --abbrev=0) mike deploy --push --update-aliases "$latest_tag" latest diff --git a/.github/workflows/validate-examples.yaml b/.github/workflows/validate-examples.yaml index 36243e6..9f66220 100644 --- a/.github/workflows/validate-examples.yaml +++ b/.github/workflows/validate-examples.yaml @@ -15,4 +15,4 @@ jobs: run: | npm i -g ajv-cli ajv-formats - name: Validate examples - run: bash script/validate-examples.sh + run: bash src/script/validate-examples.sh diff --git a/script/README.md b/script/README.md deleted file mode 100644 index 1cd84e8..0000000 --- a/script/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Script - -## Building docs - -The script [`build_docs.sh`](build_docs.sh) is used to help move some top level markdown files into the -[`docs`](../docs) directory to allow for mkdocs to create a website based on the markdown files. - -This script gets called via the [GitHub Action](../.github/workflows/docs-site-deploy.yaml) that will build and deploy -the documentation website. diff --git a/src/script/README.md b/src/script/README.md new file mode 100644 index 0000000..7154fbb --- /dev/null +++ b/src/script/README.md @@ -0,0 +1,9 @@ +# Script + +## Building docs + +The script [`build_docs.sh`](build_docs.sh) is used to help move some top level markdown files into the +[`docs`](../../docs) directory to allow for mkdocs to create a website based on the markdown files. + +This script gets called via the [GitHub Action](../../.github/workflows/docs-site-deploy.yaml) that will build and deploy +the documentation website. diff --git a/script/build_docs.sh b/src/script/build_docs.sh similarity index 100% rename from script/build_docs.sh rename to src/script/build_docs.sh diff --git a/script/generate-server-types.ruby b/src/script/generate-server-types.ruby similarity index 100% rename from script/generate-server-types.ruby rename to src/script/generate-server-types.ruby diff --git a/script/validate-examples.sh b/src/script/validate-examples.sh similarity index 85% rename from script/validate-examples.sh rename to src/script/validate-examples.sh index f344f6c..b7ac1ac 100644 --- a/script/validate-examples.sh +++ b/src/script/validate-examples.sh @@ -11,7 +11,7 @@ json_schema_version=${JSON_SCHEMA_VERSION:-v3.0.0} num_failed_validation=0 echo "Checking if $json_schema_version JSON schema is valid" -if ajv compile --spec=draft2019 -c ajv-formats -s "${script_dir}/../schema/odcs-json-schema-${json_schema_version}.json"; then +if ajv compile --spec=draft2019 -c ajv-formats -s "${script_dir}/../../schema/odcs-json-schema-${json_schema_version}.json"; then echo -e "${GREEN}Valid JSON schema${NC}" else echo -e "${RED}Invalid JSON schema, exiting${NC}" @@ -20,7 +20,7 @@ fi echo -e "Validating example ODCS files based on ${json_schema_version} JSON schema" for file in docs/examples/*/*.yaml; do - if ajv validate --spec=draft2019 -c ajv-formats -s "${script_dir}/../schema/odcs-json-schema-${json_schema_version}.json" -d "${script_dir}/../${file}"; then + if ajv validate --spec=draft2019 -c ajv-formats -s "${script_dir}/../../schema/odcs-json-schema-${json_schema_version}.json" -d "${script_dir}/../../${file}"; then echo -e "${GREEN}Passed validation, file=${file}${NC}" else num_failed_validation=$((num_failed_validation+1)) From d6e573956e5e9fddfadd78b41fdc1a9b9aa38a49 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Tue, 8 Oct 2024 16:37:45 +0800 Subject: [PATCH 71/93] Remove type from fundamentals, update README with team definition, update SLA to use Object.Element instead of Table.Column --- docs/README.md | 17 +++++++++++------ schema/odcs-json-schema-latest.json | 17 ++++++----------- schema/odcs-json-schema-v3.0.0.json | 17 ++++++----------- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/docs/README.md b/docs/README.md index 78b717a..b9b2f7a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -591,10 +591,15 @@ team: ``` ### Definitions -The UX label is the label used in the UI and other user experiences. It is not limited to BlueRacket. - -| Key | UX label | Required | Description | +| Key | UX label | Required | Description | +|-------------------------|----------------------|----------|--------------------------------------------------------------------------------------------| +| team | Team | No | Object | +| team.username | Username | No | The user's username or email. | +| team.role | Role | No | The user's job role; Examples might be owner, data steward. There is no limit on the role. | +| team.dateIn | Date In | No | The date when the user joined the team. | +| team.dateOut | Date Out | No | The date when the user ceased to be part of the team. | +| team.replacedByUsername | Replaced By Username | No | The username of the user who replaced the previous user. | ## Roles This section lists the roles that a consumer may need to access the dataset depending on the type of access they require. @@ -636,9 +641,9 @@ roles: ##
Service-Level Agreement (SLA) This section describes the service-level agreements (SLA). -* Use the `Table.Column` to indicate the number to do the checks on, as in `SELECT txn_ref_dt FROM tab1`. -* Separate multiple table.columns by a comma, as in `table1.col1`, `table2.col1`, `table1.col2`. -* If there is only one table in the contract, the table name is not required. +* Use the `Object.Element` to indicate the number to do the checks on, as in `SELECT txn_ref_dt FROM tab1`. +* Separate multiple object.element by a comma, as in `table1.col1`, `table2.col1`, `table1.col2`. +* If there is only one object in the contract, the object name is not required. ### Example diff --git a/schema/odcs-json-schema-latest.json b/schema/odcs-json-schema-latest.json index 61e0a76..bb285f2 100644 --- a/schema/odcs-json-schema-latest.json +++ b/schema/odcs-json-schema-latest.json @@ -28,11 +28,6 @@ "type": "string", "description": "Name of the data contract." }, - "type": { - "type": "string", - "description": "Identifies the types of objects in the dataset. For BigQuery or any other database, the expected value would be Tables.", - "examples": ["Tables"] - }, "tenant": { "type": "string", "description": "Indicates the property the data is primarily associated with. Value is case insensitive." @@ -2133,7 +2128,7 @@ }, "AuthoritativeDefinitions": { "type": "array", - "description": "List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", + "description": "List of links to sources that provide more details on the dataset; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", "items": { "type": "object", "properties": { @@ -2211,25 +2206,25 @@ "properties": { "username": { "type": "string", - "description": "The team's username or email." + "description": "The user's username or email." }, "role": { "type": "string", - "description": "The team's job role; Examples might be owner, data steward. There is no limit on the role." + "description": "The user's job role; Examples might be owner, data steward. There is no limit on the role." }, "dateIn": { "type": "string", "format": "date", - "description": "The date when the user became a team." + "description": "The date when the user joined the team." }, "dateOut": { "type": "string", "format": "date", - "description": "The date when the user ceased to be a team" + "description": "The date when the user ceased to be part of the team." }, "replacedByUsername": { "type": "string", - "description": "The username of the user who replaced the team" + "description": "The username of the user who replaced the previous user." } } }, diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 61e0a76..bb285f2 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -28,11 +28,6 @@ "type": "string", "description": "Name of the data contract." }, - "type": { - "type": "string", - "description": "Identifies the types of objects in the dataset. For BigQuery or any other database, the expected value would be Tables.", - "examples": ["Tables"] - }, "tenant": { "type": "string", "description": "Indicates the property the data is primarily associated with. Value is case insensitive." @@ -2133,7 +2128,7 @@ }, "AuthoritativeDefinitions": { "type": "array", - "description": "List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", + "description": "List of links to sources that provide more details on the dataset; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. Authoritative definitions follow the same structure in the standard.", "items": { "type": "object", "properties": { @@ -2211,25 +2206,25 @@ "properties": { "username": { "type": "string", - "description": "The team's username or email." + "description": "The user's username or email." }, "role": { "type": "string", - "description": "The team's job role; Examples might be owner, data steward. There is no limit on the role." + "description": "The user's job role; Examples might be owner, data steward. There is no limit on the role." }, "dateIn": { "type": "string", "format": "date", - "description": "The date when the user became a team." + "description": "The date when the user joined the team." }, "dateOut": { "type": "string", "format": "date", - "description": "The date when the user ceased to be a team" + "description": "The date when the user ceased to be part of the team." }, "replacedByUsername": { "type": "string", - "description": "The username of the user who replaced the team" + "description": "The username of the user who replaced the previous user." } } }, From ae389971e259394594a61594e5ff87ec17a7c823 Mon Sep 17 00:00:00 2001 From: Dirk Van de Poel Date: Thu, 10 Oct 2024 14:30:17 +0200 Subject: [PATCH 72/93] Update README.md Completing the list of sections and fixing some links. Signed-off-by: Dirk Van de Poel --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 01719ca..596615f 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,16 @@ Discover the [Open Data Contract Standard](docs/README.md). This file contains s ### The basics of a data contract A data contract defines the agreement between a data producer and consumers. A data contract contains several sections: -* [Fundamentals](docs/README.md#demographics). -* [Schema](docs/README.md#dataset-and-schema). -* [Data quality](docs/README.md#data-quality-). -* [Service-level agreement (SLA)](docs/README.md#service-level-agreement). -* [Security & stakeholders](docs/README.md#stakeholders). -* [Custom properties](docs/README.md#other-properties). +* [Fundamentals](docs/README.md#fundamentals). +* [Schema](docs/README.md#schema). +* [Data quality](docs/README.md#data-quality). +* [Support & communication channels](docs/README.md#support) +* [Pricing](docs/README.md#pricing) +* [Team](docs/README.md#team) +* [Roles](docs/README.md#roles) +* [Service-level agreement (SLA)](docs/README.md#sla). +* [Infrastructures & servers](docs/README.md#servers) +* [Custom properties](docs/README.md#custom-properties). ![Data contract schema](docs/img/data-contract-diagram-latest.svg "Data contract schema") From 09b14f90b38a73219364fb87090978aa81b70925 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Thu, 10 Oct 2024 20:34:10 +0800 Subject: [PATCH 73/93] Add in article about data contract tools --- resources.md | 1 + 1 file changed, 1 insertion(+) diff --git a/resources.md b/resources.md index 0e16bec..e8f8d49 100644 --- a/resources.md +++ b/resources.md @@ -2,6 +2,7 @@ ## Articles +* 2024-09-30 - [Data Contracts in Action: Tools](https://medium.com/data-engineer-things/data-contracts-in-action-tools-303bc7fbceb5) * 2024-07-17 - [Data Contracts in Action: Testing](https://medium.com/@pflooky/data-contracts-in-action-testing-111631338657) * 2024-06-12 - [The Future of Data Management: An Enabler of AI Development? A Basic Illustration with RAG, Open Standards, and Data Contracts](https://blog.owulveryck.info/2024/06/12/the-future-of-data-management-an-enabler-of-ai-development-a-basic-illustration-with-rag-open-standards-and-data-contracts.html) * 2024-05-30 - [ODCS Roadmap](https://medium.com/abeadata/odcs-roadmap-9b9a17367af4) From f39596a2bbb02fde70e24ec9fc9f6dc22f8e256e Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Thu, 10 Oct 2024 20:36:24 +0800 Subject: [PATCH 74/93] Allow docs site to deploy from dev --- .github/workflows/docs-site-deploy.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs-site-deploy.yaml b/.github/workflows/docs-site-deploy.yaml index efeccd6..1d32999 100644 --- a/.github/workflows/docs-site-deploy.yaml +++ b/.github/workflows/docs-site-deploy.yaml @@ -3,6 +3,7 @@ on: push: branches: - main + - dev permissions: contents: write jobs: From ca256411c80b8b3278b2088373328eed7d20aa8f Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Thu, 10 Oct 2024 20:40:25 +0800 Subject: [PATCH 75/93] Change checkout fetch-depth to 0 to get tags --- .github/workflows/docs-site-deploy.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docs-site-deploy.yaml b/.github/workflows/docs-site-deploy.yaml index 1d32999..36366bd 100644 --- a/.github/workflows/docs-site-deploy.yaml +++ b/.github/workflows/docs-site-deploy.yaml @@ -11,6 +11,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Configure Git Credentials run: | git config user.name github-actions[bot] From c713a48295626cb852a769eb3476b983144666fa Mon Sep 17 00:00:00 2001 From: Dirk Van de Poel Date: Thu, 10 Oct 2024 16:57:38 +0200 Subject: [PATCH 76/93] Update README.md A number of of editorial edits. Signed-off-by: Dirk Van de Poel --- docs/README.md | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/docs/README.md b/docs/README.md index 78b717a..f98b208 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color # Open Data Contract Standard ## Executive Summary -This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. It is divided in multiple sections: [fundamentals (fka demographics)](#fundamentals), [schema](#schema), [data quality](#data-quality), [pricing](#pricing), [team](#team), [roles](#roles), [service-level agreement](#sla), and [other/custom properties](#custom-properties). Each section starts with at least an example followed by definition of each field/key. +This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. It is divided in multiple sections: [fundamentals (fka demographics)](#fundamentals), [schema](#schema), [data quality](#data-quality), [Support & communication channels](#support), [pricing](#pricing), [team](#team), [roles](#roles), [service-level agreement](#sla), [Infrastructures & servers](#servers) and [other/custom properties](#custom-properties). Each section starts with at least an example followed by definition of each field/key. ## Table of content @@ -63,21 +63,21 @@ tags: null ### Definitions -| Key | UX label | Required | Description | -|-------------------------|------------------|----------|------------------------------------------------------------------------------------------| -| apiVersion | Standard version | Yes | Version of the standard used to build data contract. Default value is `v3.0.0`. | -| kind | Kind | Yes | The kind of file this is. Valid value is `DataContract`. | -| id | ID | Yes | A unique identifier used to reduce the risk of dataset name collisions, such as a UUID. | -| name | Name | No | Name of the data contract. | -| version | Version | Yes | Current version of the data contract. | -| status | Status | Yes | Current status of the data contract. | -| tenant | Tenant | No | Indicates the property the data is primarily associated with. Value is case insensitive. | -| domain | Domain | No | Name of the logical data domain. | -| dataProduct | Data Product | No | Name of the data product. | -| description | Description | No | Object containing the descriptions. | -| description.purpose | Purpose | No | Intended purpose for the provided data. | -| description.limitations | Limitations | No | Technical, compliance, and legal limitations for data use. | -| description.usage | Usage | No | Recommended usage of the data. | +| Key | UX label | Required | Description | +|-------------------------|------------------|----------|------------------------------------------------------------------------------------------------| +| apiVersion | Standard version | Yes | Version of the standard used to build data contract. Default value is `v3.0.0`. | +| kind | Kind | Yes | The kind of file this is. Valid value is `DataContract`. | +| id | ID | Yes | A unique identifier used to reduce the risk of dataset name collisions, such as a UUID. | +| name | Name | No | Name of the data contract. | +| version | Version | Yes | Current version of the data contract. | +| status | Status | Yes | Current status of the data contract. Valid values are `production`, `test`, or `development`. | +| tenant | Tenant | No | Indicates the property the data is primarily associated with. Value is case insensitive. | +| domain | Domain | No | Name of the logical data domain. | +| dataProduct | Data Product | No | Name of the data product. | +| description | Description | No | Object containing the descriptions. | +| description.purpose | Purpose | No | Intended purpose for the provided data. | +| description.limitations | Limitations | No | Technical, compliance, and legal limitations for data use. | +| description.usage | Usage | No | Recommended usage of the data. | ## Schema @@ -221,7 +221,7 @@ Note: the description needs to be updated. | physicalName | Physical Name | No | Physical name. | | description | Description | No | Description of the element. | | businessName | Business Name | No | The business name of the element. | -| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. See `authoritativeDefinitions` below. | +| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the element; examples would be a link to an external definition. See `authoritativeDefinitions` below. | | tags | Tags | No | A list of tags that may be assigned to the elements (object or property); the tags keyword may appear at any level. | #### Applicable to Objects @@ -246,8 +246,9 @@ Some keys are more applicable when the described property is a column. | unique | Unique | No | Indicates if the element contains unique values; possible values are true and false. Default is false. | | partitioned | Partitioned | No | Indicates if the element is partitioned; possible values are true and false. | | partitionKeyPosition | Partition Key Position | No | If element is used for partitioning, the position of the partition element. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1. | -| classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. Some companies like PayPal, use data classification indicating the class of data in the column; expected values are 1, 2, 3, 4, or 5. | -| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on element logic or values; examples would be URL to a GitHub repo, Collibra, on another tool. | +| classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. + | +| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on element logic or values; examples would be URL to a git repo, documentation, a data catalog or another tool. | | encryptedName | Encrypted Name | No | The element name within the dataset that contains the encrypted element value. For example, unencrypted element `email_address` might have an encryptedName of `email_address_encrypt`. | | transformSourceObjects | Transform Sources | No | List of objects in the data source used in the transformation. | | transformLogic | Transform Logic | No | Logic used in the column transformation. | @@ -286,11 +287,11 @@ Additional metadata options to more accurately define the data type. ### Authoritative definitions -Updated in ODCS (Open Data Contract Standard) v2.2.1. +Reference to an external definition on element logic or values. | Key | UX label | Required | Description | |------|-------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| type | Definition type | Yes | Type of definition for authority: v2.2.1 adds standard values: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`. | +| type | Definition type | Yes | Type of definition for authority. Valid values are: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`. | | url | URL to definition | Yes | URL to the authority. | @@ -548,7 +549,7 @@ support: ## Pricing -This section covers pricing when you bill your customer for using this data product. Pricing is experimental in v2.1.1 of the data contract. +This section covers pricing when you bill your customer for using this data product. ### Example @@ -591,7 +592,7 @@ team: ``` ### Definitions -The UX label is the label used in the UI and other user experiences. It is not limited to BlueRacket. +The UX label is the label used in the UI and other user experiences. | Key | UX label | Required | Description | @@ -1087,4 +1088,4 @@ contractCreatedTs: 2024-09-17T11:58:08Z [Check full example here.](examples/all/full-example.odcs.yaml) -All trademarks are the property of their respective owners. \ No newline at end of file +All trademarks are the property of their respective owners. From bd71d9b05ea0672fc9c48cb190e5f1f4c60e7eb0 Mon Sep 17 00:00:00 2001 From: jochenchrist Date: Sun, 13 Oct 2024 11:27:28 +0200 Subject: [PATCH 77/93] Update README.md Put data quality on property level --- docs/README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 78b717a..b944cbc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -54,10 +54,6 @@ description: limitations: null usage: null -# Data Quality -quality: null # See more information below - -# Tags tags: null ``` @@ -222,6 +218,7 @@ Note: the description needs to be updated. | description | Description | No | Description of the element. | | businessName | Business Name | No | The business name of the element. | | authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. See `authoritativeDefinitions` below. | +| quality | Quality | No | List of data quality attributes. | | tags | Tags | No | A list of tags that may be assigned to the elements (object or property); the tags keyword may appear at any level. | #### Applicable to Objects @@ -1087,4 +1084,4 @@ contractCreatedTs: 2024-09-17T11:58:08Z [Check full example here.](examples/all/full-example.odcs.yaml) -All trademarks are the property of their respective owners. \ No newline at end of file +All trademarks are the property of their respective owners. From 4f32e8b6d97c046343ab5d26244a67ced0012573 Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Tue, 15 Oct 2024 10:13:59 +0200 Subject: [PATCH 78/93] Last changes for server --- docs/README.md | 5 +--- docs/examples/server/kafka-server.odcs.yaml | 14 ++++++++++ schema/odcs-json-schema-latest.json | 31 ++------------------- schema/odcs-json-schema-v3.0.0.json | 31 ++------------------- 4 files changed, 21 insertions(+), 60 deletions(-) create mode 100644 docs/examples/server/kafka-server.odcs.yaml diff --git a/docs/README.md b/docs/README.md index 78b717a..e7c91cc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -877,7 +877,6 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| | host | Host | Yes | The bootstrap server of the kafka cluster. | -| topic | Topic | Yes | The topic name. | | format | Format | No | The format of the messages. | #### Amazon Kinesis @@ -935,7 +934,6 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | Key | UX Label | Required | Description | |--------------|-----------------|------------|------------------------------------------------------------| | project | Project | Yes | The GCP project name. | -| topic | Topic | Yes | The topic name. | #### Amazon Redshift Server [Amazon Redshift](https://aws.amazon.com/redshift/) is a power data driven decisions with the best price-performance cloud data warehouse. @@ -1036,7 +1034,6 @@ Secure File Transfer Protocol (SFTP) is a network protocol that enables secure a | serviceName | Servicename | No | Name of the service. | | stagingDir | Staging directory | No | Staging directory. | | stream | Stream | No | Name of the data stream. | -| topic | Topic | No | Topic name. | | warehouse | Warehouse | No | Name of the cluster or warehouse. | If you need another property, use [custom properties](#custom-properties). @@ -1087,4 +1084,4 @@ contractCreatedTs: 2024-09-17T11:58:08Z [Check full example here.](examples/all/full-example.odcs.yaml) -All trademarks are the property of their respective owners. \ No newline at end of file +All trademarks are the property of their respective owners. diff --git a/docs/examples/server/kafka-server.odcs.yaml b/docs/examples/server/kafka-server.odcs.yaml new file mode 100644 index 0000000..0dc94dc --- /dev/null +++ b/docs/examples/server/kafka-server.odcs.yaml @@ -0,0 +1,14 @@ +version: 1.0.0 +apiVersion: v3.0.0 +kind: DataContract +id: abc123 +status: pending +schema: + - name: Orders + physicalName: orders.avro.v1 + physicalType: topic +servers: + - server: my-kafka + type: kafka + host: pkc-7xoy1.eu-central-1.aws.confluent.cloud:9092 + format: avro diff --git a/schema/odcs-json-schema-latest.json b/schema/odcs-json-schema-latest.json index 61e0a76..61e573b 100644 --- a/schema/odcs-json-schema-latest.json +++ b/schema/odcs-json-schema-latest.json @@ -981,14 +981,6 @@ "type": "string", "description": "Staging directory." }, - "stream": { - "type": "string", - "description": "Name of the data stream." - }, - "topic": { - "type": "string", - "description": "Topic name." - }, "warehouse": { "type": "string", "description": "Name of the cluster or warehouse." @@ -1004,10 +996,6 @@ "type": "string", "description": "The bootstrap server of the kafka cluster." }, - "topic": { - "type": "string", - "description": "The topic name." - }, "format": { "type": "string", "description": "The format of the messages.", @@ -1016,8 +1004,7 @@ } }, "required": [ - "host", - "topic" + "host" ] }, "KinesisServer": { @@ -1025,10 +1012,6 @@ "title": "KinesisDataStreamsServer", "description": "Kinesis Data Streams Server", "properties": { - "stream": { - "type": "string", - "description": "The name of the Kinesis data stream." - }, "region": { "type": "string", "description": "AWS region.", @@ -1045,10 +1028,7 @@ "protobuf" ] } - }, - "required": [ - "stream" - ] + } }, "LocalServer": { "type": "object", @@ -1198,15 +1178,10 @@ "project": { "type": "string", "description": "The GCP project name." - }, - "topic": { - "type": "string", - "description": "The topic name." } }, "required": [ - "project", - "topic" + "project" ] }, "RedshiftServer": { diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 61e0a76..9d48e25 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -981,14 +981,6 @@ "type": "string", "description": "Staging directory." }, - "stream": { - "type": "string", - "description": "Name of the data stream." - }, - "topic": { - "type": "string", - "description": "Topic name." - }, "warehouse": { "type": "string", "description": "Name of the cluster or warehouse." @@ -1004,10 +996,6 @@ "type": "string", "description": "The bootstrap server of the kafka cluster." }, - "topic": { - "type": "string", - "description": "The topic name." - }, "format": { "type": "string", "description": "The format of the messages.", @@ -1016,8 +1004,7 @@ } }, "required": [ - "host", - "topic" + "host" ] }, "KinesisServer": { @@ -1025,10 +1012,6 @@ "title": "KinesisDataStreamsServer", "description": "Kinesis Data Streams Server", "properties": { - "stream": { - "type": "string", - "description": "The name of the Kinesis data stream." - }, "region": { "type": "string", "description": "AWS region.", @@ -1045,10 +1028,7 @@ "protobuf" ] } - }, - "required": [ - "stream" - ] + } }, "LocalServer": { "type": "object", @@ -1199,14 +1179,9 @@ "type": "string", "description": "The GCP project name." }, - "topic": { - "type": "string", - "description": "The topic name." - } }, "required": [ - "project", - "topic" + "project" ] }, "RedshiftServer": { From c84e5053136a29edcb932cc91d2257af49905ab4 Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Tue, 15 Oct 2024 10:21:03 +0200 Subject: [PATCH 79/93] Bugfix --- schema/odcs-json-schema-v3.0.0.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 9d48e25..61e573b 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -1178,7 +1178,7 @@ "project": { "type": "string", "description": "The GCP project name." - }, + } }, "required": [ "project" From 84ee3da382dd43939e01913bac7c324d5ef2ac56 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Tue, 15 Oct 2024 17:54:44 +0800 Subject: [PATCH 80/93] Update examples without type in top level --- docs/examples/all/full-example.odcs.yaml | 3 +- ...stgresql-adventureworks-contract.odcs.yaml | 69 ++++++++++++++++++- .../data-types/all-data-types.odcs.yaml | 2 +- .../table-column-description.odcs.yaml | 2 +- .../quality/column-accuracy.odcs.yaml | 4 +- .../quality/column-completeness.odcs.yaml | 2 +- docs/examples/quality/column-custom.odcs.yaml | 2 +- .../quality/column-validity.odcs.yaml | 2 +- .../service-and-operational-roles.odcs.yaml | 1 - .../schema/all-schema-types.odcs.yaml | 1 - docs/examples/schema/table-column.odcs.yaml | 2 +- .../table-columns-with-partition.odcs.yaml | 2 +- .../examples/sla/database-table-sla.odcs.yaml | 1 - .../stakeholders/basic-four-dpo.odcs.yaml | 1 - 14 files changed, 78 insertions(+), 16 deletions(-) diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index 6ea6a12..edf8ee5 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -15,8 +15,6 @@ tenant: ClimateQuantumInc kind: DataContract apiVersion: v3.0.0 # Standard version (follows semantic versioning) -type: tables - # Infrastructure & servers servers: - server: my-postgres @@ -30,6 +28,7 @@ servers: schema: - name: tbl physicalName: tbl_1 + physicalType: table description: Provides core payment metrics authoritativeDefinitions: - url: https://catalog.data.gov/dataset/air-quality diff --git a/docs/examples/all/postgresql-adventureworks-contract.odcs.yaml b/docs/examples/all/postgresql-adventureworks-contract.odcs.yaml index ba48a96..73950a6 100644 --- a/docs/examples/all/postgresql-adventureworks-contract.odcs.yaml +++ b/docs/examples/all/postgresql-adventureworks-contract.odcs.yaml @@ -1,13 +1,13 @@ version: "1.0.0" apiVersion: "v3.0.0" id: "6aeafdc1-ed62-4c8f-bf0a-da1061c98cdb" -type: "tables" status: "Development" kind: "DataContract" description: {} schema: - name: "department" physicalName: "department" + physicalType: "table" description: "Lookup table containing the departments within the Adventure Works\ \ Cycles company." properties: @@ -56,6 +56,7 @@ schema: required: false - name: "employee" physicalName: "employee" + physicalType: "table" description: "Employee information such as salary, department, and title." properties: - name: "businessentityid" @@ -225,6 +226,7 @@ schema: required: false - name: "employeedepartmenthistory" physicalName: "employeedepartmenthistory" + physicalType: "table" description: "Employee department transfers." properties: - name: "businessentityid" @@ -296,6 +298,7 @@ schema: required: false - name: "employeepayhistory" physicalName: "employeepayhistory" + physicalType: "table" description: "Employee pay history." properties: - name: "businessentityid" @@ -354,6 +357,7 @@ schema: required: false - name: "jobcandidate" physicalName: "jobcandidate" + physicalType: "table" description: "Résumés submitted to Human Resources by job applicants." properties: - name: "jobcandidateid" @@ -402,6 +406,7 @@ schema: required: false - name: "shift" physicalName: "shift" + physicalType: "table" description: "Work shift lookup table." properties: - name: "shiftid" @@ -460,6 +465,7 @@ schema: required: false - name: "address" physicalName: "address" + physicalType: "table" description: "Street address information for customers, employees, and vendors." properties: - name: "addressid" @@ -562,6 +568,7 @@ schema: required: false - name: "addresstype" physicalName: "addresstype" + physicalType: "table" description: "Types of addresses stored in the Address table." properties: - name: "addresstypeid" @@ -608,6 +615,7 @@ schema: required: false - name: "businessentity" physicalName: "businessentity" + physicalType: "table" description: "Source of the ID that connects vendors, customers, and employees\ \ with address and contact information." properties: @@ -644,6 +652,7 @@ schema: required: false - name: "businessentityaddress" physicalName: "businessentityaddress" + physicalType: "table" description: "Cross-reference table mapping customers, vendors, and employees\ \ to their addresses." properties: @@ -702,6 +711,7 @@ schema: required: false - name: "businessentitycontact" physicalName: "businessentitycontact" + physicalType: "table" description: "Cross-reference table mapping stores, vendors, and employees to\ \ people" properties: @@ -760,6 +770,7 @@ schema: required: false - name: "contacttype" physicalName: "contacttype" + physicalType: "table" description: "Lookup table containing the types of business entity contacts." properties: - name: "contacttypeid" @@ -796,6 +807,7 @@ schema: required: false - name: "countryregion" physicalName: "countryregion" + physicalType: "table" description: "Lookup table containing the ISO standard codes for countries and\ \ regions." properties: @@ -833,6 +845,7 @@ schema: required: false - name: "emailaddress" physicalName: "emailaddress" + physicalType: "table" description: "Where to send a person email." properties: - name: "businessentityid" @@ -891,6 +904,7 @@ schema: required: false - name: "password" physicalName: "password" + physicalType: "table" description: "One way hashed authentication information" properties: - name: "businessentityid" @@ -948,6 +962,7 @@ schema: required: false - name: "person" physicalName: "person" + physicalType: "table" description: "Human beings involved with AdventureWorks: employees, customer contacts,\ \ and vendor contacts." properties: @@ -1103,6 +1118,7 @@ schema: required: false - name: "personphone" physicalName: "personphone" + physicalType: "table" description: "Telephone number and type of a person." properties: - name: "businessentityid" @@ -1150,6 +1166,7 @@ schema: required: false - name: "phonenumbertype" physicalName: "phonenumbertype" + physicalType: "table" description: "Type of phone number of a person." properties: - name: "phonenumbertypeid" @@ -1186,6 +1203,7 @@ schema: required: false - name: "stateprovince" physicalName: "stateprovince" + physicalType: "table" description: "State and province lookup table." properties: - name: "stateprovinceid" @@ -1278,6 +1296,7 @@ schema: required: false - name: "billofmaterials" physicalName: "billofmaterials" + physicalType: "table" description: "Items required to make bicycles and bicycle subassemblies. It identifies\ \ the heirarchical relationship between a parent product and its components." properties: @@ -1381,6 +1400,7 @@ schema: required: false - name: "culture" physicalName: "culture" + physicalType: "table" description: "Lookup table containing the languages in which some AdventureWorks\ \ data is stored." properties: @@ -1418,6 +1438,7 @@ schema: required: false - name: "document" physicalName: "document" + physicalType: "table" description: "Product maintenance documents." properties: - name: "title" @@ -1566,6 +1587,7 @@ schema: required: false - name: "illustration" physicalName: "illustration" + physicalType: "table" description: "Bicycle assembly diagrams." properties: - name: "illustrationid" @@ -1602,6 +1624,7 @@ schema: required: false - name: "location" physicalName: "location" + physicalType: "table" description: "Product inventory and manufacturing locations." properties: - name: "locationid" @@ -1660,6 +1683,7 @@ schema: required: false - name: "product" physicalName: "product" + physicalType: "table" description: "Products sold or used in the manfacturing of sold products." properties: - name: "productid" @@ -1938,6 +1962,7 @@ schema: required: false - name: "productcategory" physicalName: "productcategory" + physicalType: "table" description: "High-level product categorization." properties: - name: "productcategoryid" @@ -1984,6 +2009,7 @@ schema: required: false - name: "productcosthistory" physicalName: "productcosthistory" + physicalType: "table" description: "Changes in the cost of a product over time." properties: - name: "productid" @@ -2042,6 +2068,7 @@ schema: required: false - name: "productdescription" physicalName: "productdescription" + physicalType: "table" description: "Product descriptions in several languages." properties: - name: "productdescriptionid" @@ -2088,6 +2115,7 @@ schema: required: false - name: "productdocument" physicalName: "productdocument" + physicalType: "table" description: "Cross-reference table mapping products to related product documents." properties: - name: "productid" @@ -2124,6 +2152,7 @@ schema: required: false - name: "productinventory" physicalName: "productinventory" + physicalType: "table" description: "Product inventory information." properties: - name: "productid" @@ -2203,6 +2232,7 @@ schema: required: false - name: "productlistpricehistory" physicalName: "productlistpricehistory" + physicalType: "table" description: "Changes in the list price of a product over time." properties: - name: "productid" @@ -2261,6 +2291,7 @@ schema: required: false - name: "productmodel" physicalName: "productmodel" + physicalType: "table" description: "Product model classification." properties: - name: "productmodelid" @@ -2329,6 +2360,7 @@ schema: required: false - name: "productmodelillustration" physicalName: "productmodelillustration" + physicalType: "table" description: "Cross-reference table mapping product models and illustrations." properties: - name: "productmodelid" @@ -2365,6 +2397,7 @@ schema: required: false - name: "productmodelproductdescriptionculture" physicalName: "productmodelproductdescriptionculture" + physicalType: "table" description: "Cross-reference table mapping product descriptions and the language\ \ the description is written in." properties: @@ -2413,6 +2446,7 @@ schema: required: false - name: "productphoto" physicalName: "productphoto" + physicalType: "table" description: "Product images." properties: - name: "productphotoid" @@ -2482,6 +2516,7 @@ schema: required: false - name: "productproductphoto" physicalName: "productproductphoto" + physicalType: "table" description: "Cross-reference table mapping products and product photos." properties: - name: "productid" @@ -2530,6 +2565,7 @@ schema: required: false - name: "productreview" physicalName: "productreview" + physicalType: "table" description: "Customer reviews of products they have purchased." properties: - name: "productreviewid" @@ -2622,6 +2658,7 @@ schema: required: false - name: "productsubcategory" physicalName: "productsubcategory" + physicalType: "table" description: "Product subcategories. See ProductCategory table." properties: - name: "productsubcategoryid" @@ -2679,6 +2716,7 @@ schema: required: false - name: "scrapreason" physicalName: "scrapreason" + physicalType: "table" description: "Manufacturing failure reasons lookup table." properties: - name: "scrapreasonid" @@ -2715,6 +2753,7 @@ schema: required: false - name: "transactionhistory" physicalName: "transactionhistory" + physicalType: "table" description: "Record of each purchase order, sales order, or work order transaction\ \ year to date." properties: @@ -2819,6 +2858,7 @@ schema: required: false - name: "transactionhistoryarchive" physicalName: "transactionhistoryarchive" + physicalType: "table" description: "Transactions for previous years." properties: - name: "transactionid" @@ -2922,6 +2962,7 @@ schema: required: false - name: "unitmeasure" physicalName: "unitmeasure" + physicalType: "table" description: "Unit of measure lookup table." properties: - name: "unitmeasurecode" @@ -2958,6 +2999,7 @@ schema: required: false - name: "workorder" physicalName: "workorder" + physicalType: "table" description: "Manufacturing work orders." properties: - name: "workorderid" @@ -3060,6 +3102,7 @@ schema: required: false - name: "workorderrouting" physicalName: "workorderrouting" + physicalType: "table" description: "Work order details." properties: - name: "workorderid" @@ -3196,6 +3239,7 @@ schema: required: false - name: "productvendor" physicalName: "productvendor" + physicalType: "table" description: "Cross-reference table mapping vendors with the products they supply." properties: - name: "productid" @@ -3321,6 +3365,7 @@ schema: required: false - name: "purchaseorderdetail" physicalName: "purchaseorderdetail" + physicalType: "table" description: "Individual products associated with a specific purchase order. See\ \ PurchaseOrderHeader." properties: @@ -3424,6 +3469,7 @@ schema: required: false - name: "purchaseorderheader" physicalName: "purchaseorderheader" + physicalType: "table" description: "General purchase order information. See PurchaseOrderDetail." properties: - name: "purchaseorderid" @@ -3563,6 +3609,7 @@ schema: required: false - name: "shipmethod" physicalName: "shipmethod" + physicalType: "table" description: "Shipping company lookup table." properties: - name: "shipmethodid" @@ -3631,6 +3678,7 @@ schema: required: false - name: "vendor" physicalName: "vendor" + physicalType: "table" description: "Companies from whom Adventure Works Cycles purchases parts or other\ \ goods." properties: @@ -3725,6 +3773,7 @@ schema: required: false - name: "countryregioncurrency" physicalName: "countryregioncurrency" + physicalType: "table" description: "Cross-reference table mapping ISO currency codes to a country or\ \ region." properties: @@ -3762,6 +3811,7 @@ schema: required: false - name: "creditcard" physicalName: "creditcard" + physicalType: "table" description: "Customer credit card information." properties: - name: "creditcardid" @@ -3831,6 +3881,7 @@ schema: required: false - name: "currency" physicalName: "currency" + physicalType: "table" description: "Lookup table containing standard ISO currencies." properties: - name: "currencycode" @@ -3867,6 +3918,7 @@ schema: required: false - name: "currencyrate" physicalName: "currencyrate" + physicalType: "table" description: "Currency exchange rates." properties: - name: "currencyrateid" @@ -3947,6 +3999,7 @@ schema: required: false - name: "customer" physicalName: "customer" + physicalType: "table" description: "Current customer information. Also see the Person and Store tables." properties: - name: "customerid" @@ -4016,6 +4069,7 @@ schema: required: false - name: "personcreditcard" physicalName: "personcreditcard" + physicalType: "table" description: "Cross-reference table mapping people to their credit card information\ \ in the CreditCard table." properties: @@ -4053,6 +4107,7 @@ schema: required: false - name: "salesorderdetail" physicalName: "salesorderdetail" + physicalType: "table" description: "Individual products associated with a specific sales order. See\ \ SalesOrderHeader." properties: @@ -4166,6 +4221,7 @@ schema: required: false - name: "salesorderheader" physicalName: "salesorderheader" + physicalType: "table" description: "General sales order information." properties: - name: "salesorderid" @@ -4445,6 +4501,7 @@ schema: required: false - name: "salesorderheadersalesreason" physicalName: "salesorderheadersalesreason" + physicalType: "table" description: "Cross-reference table mapping sales orders to sales reason codes." properties: - name: "salesorderid" @@ -4481,6 +4538,7 @@ schema: required: false - name: "salesperson" physicalName: "salesperson" + physicalType: "table" description: "Sales representative current information." properties: - name: "businessentityid" @@ -4582,6 +4640,7 @@ schema: required: false - name: "salespersonquotahistory" physicalName: "salespersonquotahistory" + physicalType: "table" description: "Sales performance tracking." properties: - name: "businessentityid" @@ -4639,6 +4698,7 @@ schema: required: false - name: "salesreason" physicalName: "salesreason" + physicalType: "table" description: "Lookup table of customer purchase reasons." properties: - name: "salesreasonid" @@ -4686,6 +4746,7 @@ schema: required: false - name: "salestaxrate" physicalName: "salestaxrate" + physicalType: "table" description: "Tax rate lookup table." properties: - name: "salestaxrateid" @@ -4766,6 +4827,7 @@ schema: required: false - name: "salesterritory" physicalName: "salesterritory" + physicalType: "table" description: "Sales territory lookup table." properties: - name: "territoryid" @@ -4878,6 +4940,7 @@ schema: required: false - name: "salesterritoryhistory" physicalName: "salesterritoryhistory" + physicalType: "table" description: "Sales representative transfers to other sales territories." properties: - name: "businessentityid" @@ -4946,6 +5009,7 @@ schema: required: false - name: "shoppingcartitem" physicalName: "shoppingcartitem" + physicalType: "table" description: "Contains online customer orders until the order is submitted or\ \ cancelled." properties: @@ -5016,6 +5080,7 @@ schema: required: false - name: "specialoffer" physicalName: "specialoffer" + physicalType: "table" description: "Sale discounts lookup table." properties: - name: "specialofferid" @@ -5139,6 +5204,7 @@ schema: required: false - name: "specialofferproduct" physicalName: "specialofferproduct" + physicalType: "table" description: "Cross-reference table mapping products to special offer discounts." properties: - name: "specialofferid" @@ -5185,6 +5251,7 @@ schema: required: false - name: "store" physicalName: "store" + physicalType: "table" description: "Customers (resellers) of Adventure Works products." properties: - name: "businessentityid" diff --git a/docs/examples/data-types/all-data-types.odcs.yaml b/docs/examples/data-types/all-data-types.odcs.yaml index a73f417..beddd6b 100644 --- a/docs/examples/data-types/all-data-types.odcs.yaml +++ b/docs/examples/data-types/all-data-types.odcs.yaml @@ -1,7 +1,6 @@ version: 1.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_table dataProduct: my_quantum @@ -10,6 +9,7 @@ schema: - name: transactions_tbl description: Provides core payment metrics dataGranularityDescription: Aggregation on names txn_ref_dt, pmt_txn_id + physicalType: table properties: - name: account_id physicalType: string diff --git a/docs/examples/fundamentals/table-column-description.odcs.yaml b/docs/examples/fundamentals/table-column-description.odcs.yaml index d0c1563..57a1576 100644 --- a/docs/examples/fundamentals/table-column-description.odcs.yaml +++ b/docs/examples/fundamentals/table-column-description.odcs.yaml @@ -1,7 +1,6 @@ version: 1.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_quantum apiVersion: v3.0.0 @@ -9,6 +8,7 @@ schema: - name: tbl description: Provides core payment metrics dataGranularityDescription: Aggregation on columns txn_ref_dt, pmt_txn_id + physicalType: table properties: - name: txn_ref_dt businessName: Transaction reference date diff --git a/docs/examples/quality/column-accuracy.odcs.yaml b/docs/examples/quality/column-accuracy.odcs.yaml index c0232d8..fb0a705 100644 --- a/docs/examples/quality/column-accuracy.odcs.yaml +++ b/docs/examples/quality/column-accuracy.odcs.yaml @@ -1,7 +1,6 @@ version: 1.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_table dataProduct: my_quantum @@ -13,7 +12,8 @@ schema: - url: https://catalog.data.gov/dataset/air-quality type: Reference definition on Data.gov dataGranularityDescription: Raw records - properties: + physicalType: table + properties: - name: DataValue businessName: Measured value logicalType: number diff --git a/docs/examples/quality/column-completeness.odcs.yaml b/docs/examples/quality/column-completeness.odcs.yaml index a28ea5e..f137d28 100644 --- a/docs/examples/quality/column-completeness.odcs.yaml +++ b/docs/examples/quality/column-completeness.odcs.yaml @@ -2,7 +2,6 @@ version: 1.0.0 apiVersion: v3.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_table dataProduct: my_quantum @@ -13,6 +12,7 @@ schema: - url: https://catalog.data.gov/dataset/air-quality type: Reference definition on Data.gov dataGranularityDescription: Raw records + physicalType: table properties: - name: UniqueID primaryKey: true diff --git a/docs/examples/quality/column-custom.odcs.yaml b/docs/examples/quality/column-custom.odcs.yaml index c73f1de..32d1fff 100644 --- a/docs/examples/quality/column-custom.odcs.yaml +++ b/docs/examples/quality/column-custom.odcs.yaml @@ -2,7 +2,6 @@ version: 1.0.0 apiVersion: v3.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_table dataProduct: my_quantum @@ -13,6 +12,7 @@ schema: - url: https://catalog.data.gov/dataset/air-quality type: Reference definition on Data.gov dataGranularityDescription: Raw records + physicalType: table properties: - name: UniqueID primaryKey: true diff --git a/docs/examples/quality/column-validity.odcs.yaml b/docs/examples/quality/column-validity.odcs.yaml index 98bf26a..99db211 100644 --- a/docs/examples/quality/column-validity.odcs.yaml +++ b/docs/examples/quality/column-validity.odcs.yaml @@ -2,7 +2,6 @@ version: 1.0.0 apiVersion: v3.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_table dataProduct: my_quantum @@ -13,6 +12,7 @@ schema: - url: https://catalog.data.gov/dataset/air-quality type: Reference definition on Data.gov dataGranularityDescription: Raw records + physicalType: table properties: - name: UniqueID primaryKey: true diff --git a/docs/examples/roles/service-and-operational-roles.odcs.yaml b/docs/examples/roles/service-and-operational-roles.odcs.yaml index 2766937..b51a0a3 100644 --- a/docs/examples/roles/service-and-operational-roles.odcs.yaml +++ b/docs/examples/roles/service-and-operational-roles.odcs.yaml @@ -1,7 +1,6 @@ version: 1.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_table dataProduct: my_quantum diff --git a/docs/examples/schema/all-schema-types.odcs.yaml b/docs/examples/schema/all-schema-types.odcs.yaml index 238dd88..45b02fc 100644 --- a/docs/examples/schema/all-schema-types.odcs.yaml +++ b/docs/examples/schema/all-schema-types.odcs.yaml @@ -1,7 +1,6 @@ version: 1.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_quantum apiVersion: v3.0.0 diff --git a/docs/examples/schema/table-column.odcs.yaml b/docs/examples/schema/table-column.odcs.yaml index 9079758..183807c 100644 --- a/docs/examples/schema/table-column.odcs.yaml +++ b/docs/examples/schema/table-column.odcs.yaml @@ -1,13 +1,13 @@ version: 1.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553b -type: tables status: current name: my_table dataProduct: my_quantum apiVersion: v3.0.0 schema: - name: tbl + physicalType: table properties: - name: rcvr_cntry_code businessName: Receiver country code diff --git a/docs/examples/schema/table-columns-with-partition.odcs.yaml b/docs/examples/schema/table-columns-with-partition.odcs.yaml index bd2d2f2..25a0cc1 100644 --- a/docs/examples/schema/table-columns-with-partition.odcs.yaml +++ b/docs/examples/schema/table-columns-with-partition.odcs.yaml @@ -1,13 +1,13 @@ version: 1.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553c -type: tables status: current name: my_table dataProduct: my_quantum apiVersion: v3.0.0 schema: - name: tbl + physicalType: table properties: - name: rcvr_cntry_code businessName: Receiver country code diff --git a/docs/examples/sla/database-table-sla.odcs.yaml b/docs/examples/sla/database-table-sla.odcs.yaml index 7072108..9348ab2 100644 --- a/docs/examples/sla/database-table-sla.odcs.yaml +++ b/docs/examples/sla/database-table-sla.odcs.yaml @@ -2,7 +2,6 @@ version: 1.0.0 apiVersion: v3.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_table dataProduct: my_quantum diff --git a/docs/examples/stakeholders/basic-four-dpo.odcs.yaml b/docs/examples/stakeholders/basic-four-dpo.odcs.yaml index aa38499..cc870ac 100644 --- a/docs/examples/stakeholders/basic-four-dpo.odcs.yaml +++ b/docs/examples/stakeholders/basic-four-dpo.odcs.yaml @@ -2,7 +2,6 @@ version: 1.0.0 apiVersion: v3.0.0 kind: DataContract id: 53581432-6c55-4ba2-a65f-72344a91553a -type: tables status: current name: my_table dataProduct: my_quantum From c01321f3bf454c86e3ed5b8fc824f5a6a9f27b38 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 15 Oct 2024 07:27:18 -0400 Subject: [PATCH 81/93] Update README.md --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index a52b71c..5eaefd2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -495,7 +495,7 @@ Bitol has the ambition of creating a library of common data quality rules. Join ## Support & communication channels -Support and communication channels help consumers find help regarding their use of the data contract. In version 3, ODCS opens the +Support and communication channels help consumers find help regarding their use of the data contract. ### Examples From 189fadc5a13a1642daeb7a209af4ca2c59f242d0 Mon Sep 17 00:00:00 2001 From: "Jean-Georges \"jgp\" Perrin" Date: Tue, 15 Oct 2024 07:29:53 -0400 Subject: [PATCH 82/93] Update README.md --- docs/examples/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/README.md b/docs/examples/README.md index d1dc313..984d8f5 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -1,7 +1,7 @@ # Examples of Data Contracts ## Executive summary -This folder contains mainly excerpt of data contracts to illustrate specific sections & behaviors. +This folder contains mainly excerpts of data contracts to illustrate specific sections & behaviors. ## Table of content * [Full example](#full-example) @@ -36,7 +36,7 @@ This folder contains mainly excerpt of data contracts to illustrate specific sec - [Column validity](quality/column-validity.odcs.yaml) ## Pricing -This section covers pricing when you bill your customer for using this data product. Pricing is experimental in v2.2.0 of the data contract. +This section covers pricing when you bill your customer for using this data product. ## Stakeholders From 858c4629542551bb27fa5d96cea7e0886f4e15fc Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Tue, 15 Oct 2024 20:54:16 +0800 Subject: [PATCH 83/93] Fix formatting issues in markdown that caused doc site to change text colour to blue, resolve broken links, format tables --- CHANGELOG.md | 4 +- README.md | 8 +- docs/README.md | 550 ++++++++++++++++++++------------------- src/script/build_docs.sh | 2 +- 4 files changed, 285 insertions(+), 279 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75c5c64..023e4a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,8 +83,8 @@ This document tracks the history and evolution of the **Open Data Contract Stand * Change `price.priceAmount` data type from `string` to `number`. * Change `slaProperties.value` data type from `string` to `oneOf[string, number]`. * Change `slaProperties.valueExt` data type from `string` to `oneOf[string, number]`. -* Update [examples](docs/examples) to adhere to JSON schema. -* Full example from README directs to [full-example.yaml](docs/examples/all/full-example.yaml). +* Update [examples](docs/examples/README.md) to adhere to JSON schema. +* Full example from README directs to [full-example.yaml](docs/examples/all/full-example.odcs.yaml). * Add in mkdocs for creating a [documentation website](https://bitol-io.github.io/open-data-contract-standard/). Check [building-doc.md](building-doc.md). * Add vendors page [vendors.md](vendors.md). Feel free to add anyone there. diff --git a/README.md b/README.md index 596615f..7d1fa58 100644 --- a/README.md +++ b/README.md @@ -28,12 +28,12 @@ A data contract defines the agreement between a data producer and consumers. A d * [Fundamentals](docs/README.md#fundamentals). * [Schema](docs/README.md#schema). * [Data quality](docs/README.md#data-quality). -* [Support & communication channels](docs/README.md#support) +* [Support & communication channels](docs/README.md#support-and-communication-channels) * [Pricing](docs/README.md#pricing) * [Team](docs/README.md#team) * [Roles](docs/README.md#roles) -* [Service-level agreement (SLA)](docs/README.md#sla). -* [Infrastructures & servers](docs/README.md#servers) +* [Service-level agreement (SLA)](docs/README.md#service-level-agreement-sla). +* [Infrastructures & servers](docs/README.md#infrastructure-and-servers) * [Custom properties](docs/README.md#custom-properties). ![Data contract schema](docs/img/data-contract-diagram-latest.svg "Data contract schema") @@ -49,7 +49,7 @@ validation of your YAML files. Links below show how you can import the schema: - [VS Code](https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings) ## Articles and Other Resources -Check out the [resources](./resources.md) page. +Check out the [resources](resources.md) page. ## Contributing to the project Check out the [CONTRIBUTING](./CONTRIBUTING.md) page. diff --git a/docs/README.md b/docs/README.md index 5eaefd2..33476bc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,12 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color # Open Data Contract Standard ## Executive Summary -This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. It is divided in multiple sections: [fundamentals (fka demographics)](#fundamentals), [schema](#schema), [data quality](#data-quality), [Support & communication channels](#support), [pricing](#pricing), [team](#team), [roles](#roles), [service-level agreement](#sla), [Infrastructures & servers](#servers) and [other/custom properties](#custom-properties). Each section starts with at least an example followed by definition of each field/key. +This document describes the keys and values expected in a YAML data contract, per the **Open Data Contract Standard**. +It is divided in multiple sections: [fundamentals (fka demographics)](#fundamentals), [schema](#schema), +[data quality](#data-quality), [Support & communication channels](#support-and-communication-channels), [pricing](#pricing), [team](#team), +[roles](#roles), [service-level agreement](#service-level-agreement-sla), [Infrastructures & servers](#infrastructure-and-servers) and +[other/custom properties](#custom-properties). Each section starts with at least an example followed by definition of +each field/key. ## Table of content @@ -15,12 +20,12 @@ This document describes the keys and values expected in a YAML data contract, pe 1. [Fundamentals (fka demographics)](#fundamentals) 1. [Schema](#schema) 1. [Data quality](#data-quality) -1. [Support & communication channels](#support) +1. [Support & communication channels](#support-and-communication-channels) 1. [Pricing](#pricing) 1. [Team](#team) 1. [Roles](#roles) -1. [Service-level agreement](#sla) -1. [Infrastructures & servers](#servers) +1. [Service-level agreement](#service-level-agreement-sla) +1. [Infrastructures & servers](#infrastructure-and-servers) 1. [Custom & other properties](#custom-properties) 1. [Examples](#full-example) @@ -76,7 +81,7 @@ tags: null | description.usage | Usage | No | Recommended usage of the data. | -## Schema +## Schema This section describes the schema of the data contract. It is the support for data quality, which is detailed in the next section. Schema supports both a business representation of your data and a physical implementation. It allows to tie them together. In ODCS v3, the schema has evolved from the table and column representation, therefore the schema introduces a new terminology: @@ -201,9 +206,7 @@ schema: ### Definitions -Note: the description needs to be updated. - -#### Schema +#### Schema (top level) | Key | UX label | Required | Description | |--------------------------------------------------------|------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -243,9 +246,8 @@ Some keys are more applicable when the described property is a column. | unique | Unique | No | Indicates if the element contains unique values; possible values are true and false. Default is false. | | partitioned | Partitioned | No | Indicates if the element is partitioned; possible values are true and false. | | partitionKeyPosition | Partition Key Position | No | If element is used for partitioning, the position of the partition element. Starts from 1. Example of `country, year` being partition columns, `country` has partitionKeyPosition 1 and `year` partitionKeyPosition 2. Default to -1. | -| classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. - | -| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on element logic or values; examples would be URL to a git repo, documentation, a data catalog or another tool. | +| classification | Classification | No | Can be anything, like confidential, restricted, and public to more advanced categorization. | +| authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more detail on element logic or values; examples would be URL to a git repo, documentation, a data catalog or another tool. | | encryptedName | Encrypted Name | No | The element name within the dataset that contains the encrypted element value. For example, unencrypted element `email_address` might have an encryptedName of `email_address_encrypt`. | | transformSourceObjects | Transform Sources | No | List of objects in the data source used in the transformation. | | transformLogic | Transform Logic | No | Logic used in the column transformation. | @@ -286,13 +288,13 @@ Additional metadata options to more accurately define the data type. Reference to an external definition on element logic or values. -| Key | UX label | Required | Description | -|------|-------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Key | UX label | Required | Description | +|------|-------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| | type | Definition type | Yes | Type of definition for authority. Valid values are: `businessDefinition`, `transformationImplementation`, `videoTutorial`, `tutorial`, and `implementation`. | -| url | URL to definition | Yes | URL to the authority. | +| url | URL to definition | Yes | URL to the authority. | -## Data quality +## Data quality This section describes data quality rules & parameters. They are tightly linked to the schema described in the previous section. Data quality rules support different levels/stages of data quality attributes: @@ -420,28 +422,28 @@ quality: Acronyms: * DQ: data quality. -|Key |UX label |Required| Description | -|--------------------------------|--------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|quality |Quality | No | Quality tag with all the relevant information for rule setup and execution. | -|quality.name |Name | No | A short name for the rule. | -|quality.description |Description | No | Describe the quality check to be completed. | -|quality.type |Type | No | Type of DQ rule. Valid values are `library` (default), `text`, `sql`, and `custom`. | -|quality.rule |Rule name | No | Required for `library` DQ rules: the name of the rule to be executed. | -|quality.\ |See below | No | Multiple values are allowed for the **property**, the value is the one to compare to. | -|quality.unit |Unit | No | Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed. | -|quality.validValues |Valid values | No | Static list of valid values. | -|quality.query |SQL Query | No | Required for `sql` DQ rules: the SQL query to be executed. Note that it should match the target SQL engine/database, no transalation service are provided here. | -|quality.engine |Third-party DQ Engine | No | Required for `custom` DQ rule: name of the third-party engine being used. Any value is authorized here but common values are `soda`, `greatExpectations`, `montecarlo`, etc. | -|quality.implementation |Third-party Implementation| No | A text (non-parsed) block of code required for the third-party DQ engine to run. | -|quality.dimension |Dimension | No | The key performance indicator (KPI) or dimension for data quality. Valid values are listed after the table. | -|quality.method |Method | No | Values are open and include `reconciliation`. | -|quality.severity |Severity | No | The severity of the DQ rule. | -|quality.businessImpact |Business Impact | No | Consequences of the rule failure. | -|quality.customProperties |Custom Properties | No | Additional properties required for rulee execution. Follows the same structure as any custom properties block. | -|quality.tags |Tags | No | Tags. Follows the same structure as any tags property. | -|quality.authoritativeDefinitions|Authoritative Definitions | No | Authoritative definitions indicate the link to external definition. Follows the same structure as any authoritative definitions block. | -|quality.scheduler |Scheduler | No | Name of the scheduler, can be `cron` or any tool your organization support. | -|quality.schedule |Scheduler Configuration | No | Configuration information for the scheduling tool, for `cron` a possible value is `0 20 * * *`. | +| Key | UX label | Required | Description | +|----------------------------------|----------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| quality | Quality | No | Quality tag with all the relevant information for rule setup and execution. | +| quality.name | Name | No | A short name for the rule. | +| quality.description | Description | No | Describe the quality check to be completed. | +| quality.type | Type | No | Type of DQ rule. Valid values are `library` (default), `text`, `sql`, and `custom`. | +| quality.rule | Rule name | No | Required for `library` DQ rules: the name of the rule to be executed. | +| quality.\ | See below | No | Multiple values are allowed for the **property**, the value is the one to compare to. | +| quality.unit | Unit | No | Unit the rule is using, popular values are `rows` or `percent`, but any value is allowed. | +| quality.validValues | Valid values | No | Static list of valid values. | +| quality.query | SQL Query | No | Required for `sql` DQ rules: the SQL query to be executed. Note that it should match the target SQL engine/database, no transalation service are provided here. | +| quality.engine | Third-party DQ Engine | No | Required for `custom` DQ rule: name of the third-party engine being used. Any value is authorized here but common values are `soda`, `greatExpectations`, `montecarlo`, etc. | +| quality.implementation | Third-party Implementation | No | A text (non-parsed) block of code required for the third-party DQ engine to run. | +| quality.dimension | Dimension | No | The key performance indicator (KPI) or dimension for data quality. Valid values are listed after the table. | +| quality.method | Method | No | Values are open and include `reconciliation`. | +| quality.severity | Severity | No | The severity of the DQ rule. | +| quality.businessImpact | Business Impact | No | Consequences of the rule failure. | +| quality.customProperties | Custom Properties | No | Additional properties required for rulee execution. Follows the same structure as any custom properties block. | +| quality.tags | Tags | No | Tags. Follows the same structure as any tags property. | +| quality.authoritativeDefinitions | Authoritative Definitions | No | Authoritative definitions indicate the link to external definition. Follows the same structure as any authoritative definitions block. | +| quality.scheduler | Scheduler | No | Name of the scheduler, can be `cron` or any tool your organization support. | +| quality.schedule | Scheduler Configuration | No | Configuration information for the scheduling tool, for `cron` a possible value is `0 20 * * *`. | #### Valid Values for Dimension Those data quality dimensions are used for classification and reporting in data quality. Valid values are: @@ -457,16 +459,16 @@ Those data quality dimensions are used for classification and reporting in data #### Valid Properties for Operator The operator specifies the condition to validate the rule. -|Operator |Expected Value |Math Symbol |Example | -|-------------------------|-------------------|-------------|----------------------------| -|`mustBe` |number | `=` |`mustBe: 5` | -|`mustNotBe` |number | `<>`, `≠` |`mustNotBe: 3.14` | -|`mustBeGreaterThan` |number | `>` |`mustBeGreaterThan: 59` | -|`mustBeGreaterOrEqualTo` |number | `>=`, `≥` |`mustBeGreaterOrEqualTo: 60`| -|`mustBeLessThan` |number | `<` |`mustBeLessThan: 1000` | -|`mustBeLessOrEqualTo` |number | `<=`, `≤` |`mustBeLessOrEqualTo: 999` | -|`mustBeBetween` |list of two numbers| `⊂` |`mustBeBetween: [0, 100]` | -|`mustNotBeBetween` |list of two numbers| `⊄` |`mustNotBeBetween: [0, 100]`| +| Operator | Expected Value | Math Symbol | Example | +|--------------------------|---------------------|-------------|------------------------------| +| `mustBe` | number | `=` | `mustBe: 5` | +| `mustNotBe` | number | `<>`, `≠` | `mustNotBe: 3.14` | +| `mustBeGreaterThan` | number | `>` | `mustBeGreaterThan: 59` | +| `mustBeGreaterOrEqualTo` | number | `>=`, `≥` | `mustBeGreaterOrEqualTo: 60` | +| `mustBeLessThan` | number | `<` | `mustBeLessThan: 1000` | +| `mustBeLessOrEqualTo` | number | `<=`, `≤` | `mustBeLessOrEqualTo: 999` | +| `mustBeBetween` | list of two numbers | `⊂` | `mustBeBetween: [0, 100]` | +| `mustNotBeBetween` | list of two numbers | `⊄` | `mustNotBeBetween: [0, 100]` | `mustBeBetween` is the equivalent to `mustBeGreaterThan` and `mustBeLessThan`. @@ -494,11 +496,13 @@ quality: Bitol has the ambition of creating a library of common data quality rules. Join the working group around [RFC #0012](https://github.com/bitol-io/tsc/blob/main/rfcs/0012-implicit-dq-rules.md). -## Support & communication channels +## Support and Communication Channels Support and communication channels help consumers find help regarding their use of the data contract. ### Examples +#### Minimal example + ```yaml support: - channel: channel-name-or-identifier # Simple Slack communication channel @@ -507,6 +511,8 @@ support: url: mailto:datacontract-ann@bitol.io ``` +#### Full example + ```yaml support: - channel: channel-name-or-identifier @@ -637,7 +643,7 @@ roles: | roles.secondLevelApprovers | 2nd Level Approvers | No | The name(s) of the second-level approver(s) of the role. | -## Service-Level Agreement (SLA) +## Service-Level Agreement (SLA) This section describes the service-level agreements (SLA). * Use the `Object.Element` to indicate the number to do the checks on, as in `SELECT txn_ref_dt FROM tab1`. @@ -691,7 +697,7 @@ slaProperties: | slaProperties.element | Element(s) | No | Element(s) to check on. Multiple elements should be extremely rare and, if so, separated by commas. | | slaProperties.driver | Driver | No | Describes the importance of the SLA from the list of: `regulatory`, `analytics`, or `operational`. | -## Infrastructure & Servers +## Infrastructure and Servers The `servers` element describes where the data protected by this data contract is *physically* located. That metadata helps to know where the data is so that a data consumer can discover the data and a platform engineer can automate access. @@ -736,138 +742,138 @@ Each server type can be customized with different properties such as `host`, `po If your server is not in the list, please use [custom](#custom-server) and suggest it as an improvement. Possible values for `type` are: - [api](#api-server) -- [athena](#athena-server) +- [athena](#amazon-athena-server) - [azure](#azure-server) -- [bigquery](#bigquery-server) +- [bigquery](#google-bigquery) - [clickhouse](#clickhouse-server) - [databricks](#databricks-server) -- [db2](#ibmdb2-server) +- [db2](#ibm-db2-server) - [denodo](#denodo-server) - [dremio](#dremio-server) - [duckdb](#duckdb-server) -- [glue](#glue-server) -- [cloudsql](#googlecloudsql-server) -- [informix](#informix-server) +- [glue](#amazon-glue) +- [cloudsql](#google-cloud-sql) +- [informix](#ibm-informix-and-hcl-informix) - [kafka](#kafka-server) -- [kinesis](#kinesis-server) -- [local](#local-server) +- [kinesis](#amazon-kinesis) +- [local](#local-files) - [mysql](#mysql-server) -- [oracle](#oracle-server) -- [postgresql](#postgres-server) +- [oracle](#oracle) +- [postgresql](#postgresql) - [presto](#presto-server) -- [pubsub](#pubsub-server) -- [redshift](#redshift-server) -- [s3](#s3-server) +- [pubsub](#google-pubsub) +- [redshift](#amazon-redshift-server) +- [s3](#amazon-s3-server-and-compatible-servers) - [sftp](#sftp-server) -- [snowflake](#snowflake-server) -- [sqlserver](#sqlserver-server) +- [snowflake](#snowflake) +- [sqlserver](#microsoft-sql-server) - [synapse](#synapse-server) - [trino](#trino-server) - [vertica](#vertica-server) -## API Server +### API Server | Key | UX Label | Required | Description | |----------------|------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **location** | Location | Yes | URL to the API | -#### Amazon Athena Server +#### Amazon Athena Server [Amazon Athena](https://docs.aws.amazon.com/athena/latest/ug/what-is.html) is an interactive query service that makes it easy to analyze data directly in Amazon Simple Storage Service (Amazon S3) using standard SQL. With a few actions in the AWS Management Console, you can point Athena at your data stored in Amazon S3 and begin using standard SQL to run ad-hoc queries and get results in seconds. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| schema | Schema | Yes | Identify the schema in the data source in which your tables exist. | -| stagingDir | Stagingdir | No | Amazon Athena automatically stores query results and metadata information for each query that runs in a query result location that you can specify in Amazon S3. | -| catalog | Catalog | No | Identify the name of the Data Source, also referred to as a Catalog. | -| regionName | Regionname | No | The region your AWS account uses. | +| Key | UX Label | Required | Description | +|------------|-------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| schema | Schema | Yes | Identify the schema in the data source in which your tables exist. | +| stagingDir | Staging Directory | No | Amazon Athena automatically stores query results and metadata information for each query that runs in a query result location that you can specify in Amazon S3. | +| catalog | Catalog | No | Identify the name of the Data Source, also referred to as a Catalog. | +| regionName | Region Name | No | The region your AWS account uses. | -#### Azure Server +#### Azure Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| location | Location | Yes | Fully qualified path to Azure Blob Storage or Azure Data Lake Storage (ADLS), supports globs. | -| format | Format | Yes | File format. | -| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | +| Key | UX Label | Required | Description | +|-----------|-----------|----------|-----------------------------------------------------------------------------------------------| +| location | Location | Yes | Fully qualified path to Azure Blob Storage or Azure Data Lake Storage (ADLS), supports globs. | +| format | Format | Yes | File format. | +| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | -#### Google BigQuery +#### Google BigQuery [BigQuery](https://cloud.google.com/bigquery) is a fully managed, AI-ready data analytics platform that helps you maximize value from your data and is designed to be multi-engine, multi-format, and multi-cloud. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| project | Project | Yes | The Google Cloud Platform (GCP) project name. | -| dataset | Dataset | Yes | The GCP dataset name. | +| Key | UX Label | Required | Description | +|---------|----------|----------|-----------------------------------------------| +| project | Project | Yes | The Google Cloud Platform (GCP) project name. | +| dataset | Dataset | Yes | The GCP dataset name. | -#### ClickHouse Server +#### ClickHouse Server [ClickHouse](https://clickhouse.com/) is an open-source column-oriented database management system that allows generating analytical data reports in real-time. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the ClickHouse server. | -| port | Port | Yes | The port to the ClickHouse server. | -| database | Database | Yes | The name of the database. | +| Key | UX Label | Required | Description | +|----------|----------|----------|------------------------------------| +| host | Host | Yes | The host of the ClickHouse server. | +| port | Port | Yes | The port to the ClickHouse server. | +| database | Database | Yes | The name of the database. | -#### Google Cloud SQL +#### Google Cloud SQL [Google Cloud SQL](https://cloud.google.com/sql) is a fully managed, cost-effective relational database service for PostgreSQL, MySQL, and SQL Server. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the Google Cloud SQL server. | -| port | Port | Yes | The port of the Google Cloud SQL server. | -| database | Database | Yes | The name of the database. | -| schema | Schema | Yes | The name of the schema. | +| Key | UX Label | Required | Description | +|----------|----------|----------|------------------------------------------| +| host | Host | Yes | The host of the Google Cloud SQL server. | +| port | Port | Yes | The port of the Google Cloud SQL server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | Yes | The name of the schema. | -#### Databricks Server +#### Databricks Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| catalog | Catalog | Yes | The name of the Hive or Unity catalog | -| schema | Schema | Yes | The schema name in the catalog | -| host | Host | No | The Databricks host | +| Key | UX Label | Required | Description | +|---------|----------|----------|---------------------------------------| +| catalog | Catalog | Yes | The name of the Hive or Unity catalog | +| schema | Schema | Yes | The schema name in the catalog | +| host | Host | No | The Databricks host | -#### IBM Db2 Server +#### IBM Db2 Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the IBM DB2 server. | -| port | Port | Yes | The port of the IBM DB2 server. | -| database | Database | Yes | The name of the database. | -| schema | Schema | No | The name of the schema. | +| Key | UX Label | Required | Description | +|----------|----------|----------|---------------------------------| +| host | Host | Yes | The host of the IBM DB2 server. | +| port | Port | Yes | The port of the IBM DB2 server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | No | The name of the schema. | -#### Denodo Server +#### Denodo Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the Denodo server. | -| port | Port | Yes | The port of the Denodo server. | -| database | Database | No | The name of the database. | +| Key | UX Label | Required | Description | +|----------|----------|----------|--------------------------------| +| host | Host | Yes | The host of the Denodo server. | +| port | Port | Yes | The port of the Denodo server. | +| database | Database | No | The name of the database. | -#### Dremio Server +#### Dremio Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the Dremio server. | -| port | Port | Yes | The port of the Dremio server. | -| schema | Schema | No | The name of the schema. | +| Key | UX Label | Required | Description | +|--------|----------|----------|--------------------------------| +| host | Host | Yes | The host of the Dremio server. | +| port | Port | Yes | The port of the Dremio server. | +| schema | Schema | No | The name of the schema. | -#### DuckDB Server +#### DuckDB Server [DuckDB](https://duckdb.org/) supports a feature-rich SQL dialect complemented with deep integrations into client APIs. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| database | Database | Yes | Path to duckdb database file. | -| schema | Schema | No | The name of the schema. | +| Key | UX Label | Required | Description | +|----------|----------|----------|-------------------------------| +| database | Database | Yes | Path to duckdb database file. | +| schema | Schema | No | The name of the schema. | -#### Amazon Glue +#### Amazon Glue -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| account | Account | Yes | The AWS Glue account | -| database | Database | Yes | The AWS Glue database name | -| location | Location | No | The AWS S3 path. Must be in the form of a URL. | -| format | Format | No | The format of the files | +| Key | UX Label | Required | Description | +|----------|----------|----------|------------------------------------------------| +| account | Account | Yes | The AWS Glue account | +| database | Database | Yes | The AWS Glue database name | +| location | Location | No | The AWS S3 path. Must be in the form of a URL. | +| format | Format | No | The format of the files | -#### IBM Informix & HCL Informix +#### IBM Informix and HCL Informix [IBM Informix](https://www.ibm.com/products/informix) is a high performance, always-on, highly scalable and easily embeddable enterprise-class database optimized for the most demanding transactional and analytics workloads. As an object-relational engine, IBM Informix seamlessly integrates the best of relational and object-oriented capabilities enabling the flexible modeling of complex data structures and relationships. | Key | UX Label | Required | Description | @@ -876,177 +882,177 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | port | Port | No | The port to the Informix server. Defaults to 9088. | | database | Database | Yes | The name of the database. | -#### Kafka Server +#### Kafka Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The bootstrap server of the kafka cluster. | -| topic | Topic | Yes | The topic name. | -| format | Format | No | The format of the messages. | +| Key | UX Label | Required | Description | +|--------|----------|----------|--------------------------------------------| +| host | Host | Yes | The bootstrap server of the kafka cluster. | +| topic | Topic | Yes | The topic name. | +| format | Format | No | The format of the messages. | -#### Amazon Kinesis +#### Amazon Kinesis -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| stream | Stream | Yes | The name of the Kinesis data stream. | -| region | Region | No | AWS region. | -| format | Format | No | The format of the record | +| Key | UX Label | Required | Description | +|--------|----------|----------|--------------------------------------| +| stream | Stream | Yes | The name of the Kinesis data stream. | +| region | Region | No | AWS region. | +| format | Format | No | The format of the record | -#### Local Files +#### Local Files -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| path | Path | Yes | The relative or absolute path to the data file(s). | -| format | Format | Yes | The format of the file(s) | +| Key | UX Label | Required | Description | +|--------|----------|----------|----------------------------------------------------| +| path | Path | Yes | The relative or absolute path to the data file(s). | +| format | Format | Yes | The format of the file(s) | -#### MySQL Server +#### MySQL Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the MySql server. | -| port | Port | No | The port of the MySql server. Defaults to 3306. | -| database | Database | Yes | The name of the database. | +| Key | UX Label | Required | Description | +|----------|----------|----------|-------------------------------------------------| +| host | Host | Yes | The host of the MySql server. | +| port | Port | No | The port of the MySql server. Defaults to 3306. | +| database | Database | Yes | The name of the database. | -#### Oracle +#### Oracle -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host to the Oracle server | -| port | Port | Yes | The port to the Oracle server. | -| serviceName | Service Name | Yes | The name of the service. | +| Key | UX Label | Required | Description | +|-------------|--------------|----------|--------------------------------| +| host | Host | Yes | The host to the Oracle server | +| port | Port | Yes | The port to the Oracle server. | +| serviceName | Service Name | Yes | The name of the service. | -#### PostgreSQL +#### PostgreSQL [PostgreSQL](https://www.postgresql.org/) is a powerful, open source object-relational database system with over 35 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host to the PostgreSQL server | -| port | Port | No | The port to the PostgreSQL server. Defaults to 5432. | -| database | Database | Yes | The name of the database. | -| schema | Schema | No | The name of the schema in the database. | +| Key | UX Label | Required | Description | +|----------|----------|----------|------------------------------------------------------| +| host | Host | Yes | The host to the PostgreSQL server | +| port | Port | No | The port to the PostgreSQL server. Defaults to 5432. | +| database | Database | Yes | The name of the database. | +| schema | Schema | No | The name of the schema in the database. | -#### Presto Server +#### Presto Server -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host to the Presto server | -| catalog | Catalog | No | The name of the catalog. | -| schema | Schema | No | The name of the schema. | +| Key | UX Label | Required | Description | +|---------|----------|----------|-------------------------------| +| host | Host | Yes | The host to the Presto server | +| catalog | Catalog | No | The name of the catalog. | +| schema | Schema | No | The name of the schema. | -#### Google Pub/Sub +#### Google Pub/Sub [Google Cloud](https://cloud.google.com/pubsub) service to Ingest events for streaming into BigQuery, data lakes or operational databases. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| project | Project | Yes | The GCP project name. | -| topic | Topic | Yes | The topic name. | +| Key | UX Label | Required | Description | +|---------|----------|----------|-----------------------| +| project | Project | Yes | The GCP project name. | +| topic | Topic | Yes | The topic name. | -#### Amazon Redshift Server +#### Amazon Redshift Server [Amazon Redshift](https://aws.amazon.com/redshift/) is a power data driven decisions with the best price-performance cloud data warehouse. -| Key | UX Label | Required | Description | -|--------------|-----------------|----------|------------------------------------------------------------| -| database | Database | Yes | The name of the database. | -| schema | Schema | Yes | The name of the schema. | -| host | Host | No | An optional string describing the server. | -| region | Region | No | AWS region of Redshift server. | -| account | Account | No | The account used by the server. | +| Key | UX Label | Required | Description | +|----------|----------|----------|-------------------------------------------| +| database | Database | Yes | The name of the database. | +| schema | Schema | Yes | The name of the schema. | +| host | Host | No | An optional string describing the server. | +| region | Region | No | AWS region of Redshift server. | +| account | Account | No | The account used by the server. | -#### Amazon S3 Server and Compatible Servers +#### Amazon S3 Server and Compatible Servers [Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) is an object storage service offering industry-leading scalability, data availability, security, and performance. Millions of customers of all sizes and industries store, manage, analyze, and protect any amount of data for virtually any use case, such as data lakes, cloud-native applications, and mobile apps. Other vendors have implemented a compatible implementation of S3. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| location | Location | Yes | S3 URL, starting with `s3://` | -| endpointUrl | Endpointurl | No | The server endpoint for S3-compatible servers. | -| format | Format | No | File format. | -| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | +| Key | UX Label | Required | Description | +|-------------|--------------|----------|-----------------------------------------------------------------------------------| +| location | Location | Yes | S3 URL, starting with `s3://` | +| endpointUrl | Endpoint URL | No | The server endpoint for S3-compatible servers. | +| format | Format | No | File format. | +| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | -#### SFTP Server +#### SFTP Server Secure File Transfer Protocol (SFTP) is a network protocol that enables secure and encrypted file transfers between a client and a server. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| location | Location | Yes | SFTP URL, starting with `sftp://`. The URL should include the port number. | -| format | Format | No | File format. | -| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | +| Key | UX Label | Required | Description | +|-----------|-----------|----------|-----------------------------------------------------------------------------------| +| location | Location | Yes | SFTP URL, starting with `sftp://`. The URL should include the port number. | +| format | Format | No | File format. | +| delimiter | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | -#### Snowflake +#### Snowflake -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host to the Snowflake server | -| port | Port | Yes | The port to the Snowflake server. | -| account | Account | Yes | The Snowflake account used by the server. | -| database | Database | Yes | The name of the database. | -| warehouse | Warehouse | Yes | The name of the cluster of resources that is a Snowflake virtual warehouse. | -| schema | Schema | Yes | The name of the schema. | - -#### Microsoft SQL Server -[Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server/sql-server-downloads) is a proprietary relational database management system developed by Microsoft. - -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host to the database server | -| port | Port | No | The port to the database server. Defaults to 1433. | -| database | Database | Yes | The name of the database. | -| schema | Schema | Yes | The name of the schema in the database. | - -#### Synapse Server - -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the Synapse server. | -| port | Port | Yes | The port of the Synapse server. | -| database | Database | Yes | The name of the database. | +| Key | UX Label | Required | Description | +|-----------|-----------|----------|-----------------------------------------------------------------------------| +| host | Host | Yes | The host to the Snowflake server | +| port | Port | Yes | The port to the Snowflake server. | +| account | Account | Yes | The Snowflake account used by the server. | +| database | Database | Yes | The name of the database. | +| warehouse | Warehouse | Yes | The name of the cluster of resources that is a Snowflake virtual warehouse. | +| schema | Schema | Yes | The name of the schema. | -#### Trino Server - -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The Trino host URL. | -| port | Port | Yes | The Trino port. | -| catalog | Catalog | Yes | The name of the catalog. | -| schema | Schema | Yes | The name of the schema in the database. | - -#### Vertica Server +#### Microsoft SQL Server +[Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server/sql-server-downloads) is a proprietary relational database management system developed by Microsoft. -| Key | UX Label | Required | Description | -|--------------|-----------------|------------|------------------------------------------------------------| -| host | Host | Yes | The host of the Vertica server. | -| port | Port | Yes | The port of the Vertica server. | -| database | Database | Yes | The name of the database. | -| schema | Schema | Yes | The name of the schema. | - -#### Custom Server - -| Key | UX Label | Required | Description | -|--------------|-------------------|------------|---------------------------------------------------------------------| -| account | Account | No | Account used by the server. | -| catalog | Catalog | No | Name of the catalog. | -| database | Database | No | Name of the database. | -| dataset | Dataset | No | Name of the dataset. | -| delimiter | Delimiter | No | Delimiter. | -| endpointUrl | Endpoint URL | No | Server endpoint. | -| format | Format | No | File format. | -| host | Host | No | Host name or IP address. | -| location | Location | No | A URL to a location. | -| path | Path | No | Relative or absolute path to the data file(s). | -| port | Port | No | Port to the server. No default value is assumed for custom servers. | -| project | Project | No | Project name. | -| region | Region | No | Cloud region. | -| regionName | Regionname | No | Region name. | -| schema | Schema | No | Name of the schema. | -| serviceName | Servicename | No | Name of the service. | -| stagingDir | Staging directory | No | Staging directory. | -| stream | Stream | No | Name of the data stream. | -| topic | Topic | No | Topic name. | -| warehouse | Warehouse | No | Name of the cluster or warehouse. | +| Key | UX Label | Required | Description | +|----------|----------|----------|----------------------------------------------------| +| host | Host | Yes | The host to the database server | +| port | Port | No | The port to the database server. Defaults to 1433. | +| database | Database | Yes | The name of the database. | +| schema | Schema | Yes | The name of the schema in the database. | + +#### Synapse Server + +| Key | UX Label | Required | Description | +|----------|----------|----------|---------------------------------| +| host | Host | Yes | The host of the Synapse server. | +| port | Port | Yes | The port of the Synapse server. | +| database | Database | Yes | The name of the database. | + +#### Trino Server + +| Key | UX Label | Required | Description | +|---------|----------|----------|-----------------------------------------| +| host | Host | Yes | The Trino host URL. | +| port | Port | Yes | The Trino port. | +| catalog | Catalog | Yes | The name of the catalog. | +| schema | Schema | Yes | The name of the schema in the database. | + +#### Vertica Server + +| Key | UX Label | Required | Description | +|----------|----------|----------|---------------------------------| +| host | Host | Yes | The host of the Vertica server. | +| port | Port | Yes | The port of the Vertica server. | +| database | Database | Yes | The name of the database. | +| schema | Schema | Yes | The name of the schema. | + +#### Custom Server + +| Key | UX Label | Required | Description | +|-------------|-------------------|----------|---------------------------------------------------------------------| +| account | Account | No | Account used by the server. | +| catalog | Catalog | No | Name of the catalog. | +| database | Database | No | Name of the database. | +| dataset | Dataset | No | Name of the dataset. | +| delimiter | Delimiter | No | Delimiter. | +| endpointUrl | Endpoint URL | No | Server endpoint. | +| format | Format | No | File format. | +| host | Host | No | Host name or IP address. | +| location | Location | No | A URL to a location. | +| path | Path | No | Relative or absolute path to the data file(s). | +| port | Port | No | Port to the server. No default value is assumed for custom servers. | +| project | Project | No | Project name. | +| region | Region | No | Cloud region. | +| regionName | Region Name | No | Region name. | +| schema | Schema | No | Name of the schema. | +| serviceName | Service Name | No | Name of the service. | +| stagingDir | Staging Directory | No | Staging directory. | +| stream | Stream | No | Name of the data stream. | +| topic | Topic | No | Topic name. | +| warehouse | Warehouse | No | Name of the cluster or warehouse. | If you need another property, use [custom properties](#custom-properties). -## Custom Properties +## Custom Properties This section covers custom properties you may find in a data contract. ### Example diff --git a/src/script/build_docs.sh b/src/script/build_docs.sh index 1a5f56c..473cc57 100644 --- a/src/script/build_docs.sh +++ b/src/script/build_docs.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash echo "Moving top level markdown files into 'docs' folder" -cat README.md | sed 's/(docs\//(/g' | sed 's/CONTRIBUTING.md/contributing.md/g' > docs/home.md +cat README.md | sed 's/(docs\//(/g' | sed 's/CONTRIBUTING.md/contributing.md/g' | sed 's/resources.md/\.\.\/resources.md/g' > docs/home.md cat CHANGELOG.md | sed 's/(docs\//(/g' > docs/changelog.md cp CONTRIBUTING.md docs/contributing.md cp vendors.md docs/vendors.md From 2e6ae5ff5a149e1abd3f6fc18ccd887fd2196f9f Mon Sep 17 00:00:00 2001 From: Simon Harrer Date: Thu, 17 Oct 2024 15:32:57 +0200 Subject: [PATCH 84/93] Add custom properties in schema --- docs/README.md | 1 + docs/examples/all/full-example.odcs.yaml | 10 +++++++++- schema/odcs-json-schema-latest.json | 3 +++ schema/odcs-json-schema-v3.0.0.json | 3 +++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 06a3c82..3467422 100644 --- a/docs/README.md +++ b/docs/README.md @@ -220,6 +220,7 @@ Note: the description needs to be updated. | authoritativeDefinitions | Authoritative Definitions | No | List of links to sources that provide more details on the table; examples would be a link to an external definition, a training video, a GitHub repo, Collibra, or another tool. See `authoritativeDefinitions` below. | | quality | Quality | No | List of data quality attributes. | | tags | Tags | No | A list of tags that may be assigned to the elements (object or property); the tags keyword may appear at any level. | +| customProperties | Custom Properties | No | Custom properties that are not part of the standard. | #### Applicable to Objects diff --git a/docs/examples/all/full-example.odcs.yaml b/docs/examples/all/full-example.odcs.yaml index edf8ee5..3dfffe2 100644 --- a/docs/examples/all/full-example.odcs.yaml +++ b/docs/examples/all/full-example.odcs.yaml @@ -60,6 +60,9 @@ schema: examples: - "2022-10-03" - "2020-01-28" + customProperties: + - property: anonymizationStrategy + value: none - name: rcvr_id primaryKey: true primaryKeyPosition: 1 @@ -120,6 +123,11 @@ schema: businessImpact: operational schedule: 0 20 * * * scheduler: cron + customProperties: + - property: business-key + value: + - txn_ref_dt + - rcvr_id # Pricing @@ -205,7 +213,7 @@ support: tool: email url: mailto:datacontract-ann@bitol.io - channel: Feedback # Product Feedback - description: General Product Feedback (Public) + description: General Product Feedback (Public) url: https://product-feedback.com # Tags diff --git a/schema/odcs-json-schema-latest.json b/schema/odcs-json-schema-latest.json index 955bffa..1ecb880 100644 --- a/schema/odcs-json-schema-latest.json +++ b/schema/odcs-json-schema-latest.json @@ -1476,6 +1476,9 @@ }, "tags": { "$ref": "#/$defs/Tags" + }, + "customProperties": { + "$ref": "#/$defs/CustomProperties" } } }, diff --git a/schema/odcs-json-schema-v3.0.0.json b/schema/odcs-json-schema-v3.0.0.json index 955bffa..1ecb880 100644 --- a/schema/odcs-json-schema-v3.0.0.json +++ b/schema/odcs-json-schema-v3.0.0.json @@ -1476,6 +1476,9 @@ }, "tags": { "$ref": "#/$defs/Tags" + }, + "customProperties": { + "$ref": "#/$defs/CustomProperties" } } }, From f6943bdbf4b3ee97577672d7a4620474a17ac60d Mon Sep 17 00:00:00 2001 From: "Dr. Simon Harrer" Date: Thu, 17 Oct 2024 15:37:13 +0200 Subject: [PATCH 85/93] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75c5c64..07bd125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ This document tracks the history and evolution of the **Open Data Contract Stand # v3.0.0 - 2024-10-05 - IN REVIEW -* **New section**: Support & communication channels. +* **New section**: Support & communication channels. +* **New section**: Servers. * **Changes** to fundamentals : * Rename `uuid` to `id`. * Add `name`. From 779cdda6d7a812f2a1a04ed788b8933ab13aa88f Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Fri, 18 Oct 2024 11:26:38 +0800 Subject: [PATCH 86/93] Fix formatting --- docs/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 41f14bb..7c94ccc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -299,6 +299,7 @@ Reference to an external definition on element logic or values. This section describes data quality rules & parameters. They are tightly linked to the schema described in the previous section. Data quality rules support different levels/stages of data quality attributes: + - __Text__: A human-readable text that describes the quality of the data. - __Library__ rules: A maintained library of commonly-used predefined quality attributes such as `rowCount`, `unique`, `freshness`, and more. - __SQL__: An individual SQL query that returns a value that can be compared. Can be extended to `Python` or other. @@ -772,7 +773,7 @@ If your server is not in the list, please use [custom](#custom-server) and sugge - [trino](#trino-server) - [vertica](#vertica-server) -### API Server +#### API Server | Key | UX Label | Required | Description | |----------------|------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| From 7f125a910eca7c22945808a50cae330ddd5cbe5d Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Fri, 18 Oct 2024 14:37:29 +0800 Subject: [PATCH 87/93] Add in all examples to example doc, create markdown files for examples and link when creating docs --- docs/README.md | 2 +- docs/examples/README.md | 10 +++++++++- src/script/build_docs.sh | 20 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 7c94ccc..26d0b69 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,7 +27,7 @@ each field/key. 1. [Service-level agreement](#service-level-agreement-sla) 1. [Infrastructures & servers](#infrastructure-and-servers) 1. [Custom & other properties](#custom-properties) -1. [Examples](#full-example) +1. [Examples](#full-example-1) ## Notes diff --git a/docs/examples/README.md b/docs/examples/README.md index 984d8f5..fb75e18 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -9,6 +9,7 @@ This folder contains mainly excerpts of data contracts to illustrate specific se * [Datasets & schema](#dataset-and-schema) * [Data quality](#data-quality) * [Pricing](#pricing) +* [Server](#server) * [Stakeholders](#stakeholders) * [Roles](#roles) * [Service-level agreement](#service-level-agreement) @@ -25,16 +26,23 @@ This folder contains mainly excerpts of data contracts to illustrate specific se ## Dataset and schema +- [All schema types](schema/all-schema-types.odcs.yaml) +- [Data types](data-types/all-data-types.odcs.yaml) - [Table with single column](schema/table-column.odcs.yaml) - [Table with columns and partitioning](schema/table-columns-with-partition.odcs.yaml) -- [Data types](data-types/all-data-types.odcs.yaml) ## Data quality - [Column accuracy](quality/column-accuracy.odcs.yaml) - [Column completeness](quality/column-completeness.odcs.yaml) +- [Column custom](quality/column-custom.odcs.yaml) - [Column validity](quality/column-validity.odcs.yaml) +## Server + +- [Azure server](server/azure-server.odcs.yaml) +- [Kafka server](server/kafka-server.odcs.yaml) + ## Pricing This section covers pricing when you bill your customer for using this data product. diff --git a/src/script/build_docs.sh b/src/script/build_docs.sh index 473cc57..9dc6116 100644 --- a/src/script/build_docs.sh +++ b/src/script/build_docs.sh @@ -5,3 +5,23 @@ cat README.md | sed 's/(docs\//(/g' | sed 's/CONTRIBUTING.md/contributing.md/g' cat CHANGELOG.md | sed 's/(docs\//(/g' > docs/changelog.md cp CONTRIBUTING.md docs/contributing.md cp vendors.md docs/vendors.md + +echo "Creating markdown file for each example" +for f in docs/examples/**/*.yaml; do + yaml_content=$(cat "$f") + markdown_file_path="${f//odcs.yaml/md}" + header="${f//docs\/examples\//}" + echo "Creating file: $markdown_file_path" + content=$(cat <<-END +# ${header} + +\`\`\`yaml +${yaml_content} +\`\`\` +END +) + echo "$content" > "$markdown_file_path" + escaped_header="${header//\//\\/}" + replacement_link="${escaped_header//odcs.yaml/md}" + sed -i '' -e "s/$escaped_header/$replacement_link/g" docs/examples/README.md +done From 6b9c868d84cbdff86f6643747fbe6622f92e3fd5 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Fri, 18 Oct 2024 14:40:08 +0800 Subject: [PATCH 88/93] Fix sed command --- src/script/build_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/build_docs.sh b/src/script/build_docs.sh index 9dc6116..5851fa0 100644 --- a/src/script/build_docs.sh +++ b/src/script/build_docs.sh @@ -23,5 +23,5 @@ END echo "$content" > "$markdown_file_path" escaped_header="${header//\//\\/}" replacement_link="${escaped_header//odcs.yaml/md}" - sed -i '' -e "s/$escaped_header/$replacement_link/g" docs/examples/README.md + sed -i -e "s/$escaped_header/$replacement_link/g" docs/examples/README.md done From aec155e96a226afdef442be96b0e9b49fac48a71 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Fri, 18 Oct 2024 15:14:56 +0800 Subject: [PATCH 89/93] Add in dynamic nav for examples --- .github/workflows/docs-site-deploy.yaml | 2 +- .gitignore | 7 ++++++ docs/examples/README.md | 32 ++++++++++++------------- mkdocs.yml | 5 +++- src/script/build_docs.sh | 8 ++++--- 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/.github/workflows/docs-site-deploy.yaml b/.github/workflows/docs-site-deploy.yaml index 36366bd..2c93766 100644 --- a/.github/workflows/docs-site-deploy.yaml +++ b/.github/workflows/docs-site-deploy.yaml @@ -27,7 +27,7 @@ jobs: path: .cache restore-keys: | mkdocs-material- - - run: pip install mkdocs-material mkdocs-open-in-new-tab "mkdocs-material[imaging]" mike + - run: pip install mkdocs-material mkdocs-open-in-new-tab "mkdocs-material[imaging]" mkdocs-awesome-pages-plugin mike - run: bash src/script/build_docs.sh - run: | latest_tag=$(git describe --tags --abbrev=0) diff --git a/.gitignore b/.gitignore index 10b3150..a0889dc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,10 @@ .idea site *.iml +.cache + +docs/changelog.md +docs/contributing.md +docs/home.md +docs/vendors.md +docs/examples/**/*.md \ No newline at end of file diff --git a/docs/examples/README.md b/docs/examples/README.md index fb75e18..aab8fc0 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -17,46 +17,46 @@ This folder contains mainly excerpts of data contracts to illustrate specific se ## Full example -- [Full example](all/full-example.odcs.yaml) -- [Postgres AdventureWorks](all/postgresql-adventureworks-contract.odcs.yaml) +- [Full example](all/full-example.md) +- [Postgres AdventureWorks](all/postgresql-adventureworks-contract.md) ## Fundamentals -- [Table and column](fundamentals/table-column-description.odcs.yaml) +- [Table and column](fundamentals/table-column-description.md) ## Dataset and schema -- [All schema types](schema/all-schema-types.odcs.yaml) -- [Data types](data-types/all-data-types.odcs.yaml) -- [Table with single column](schema/table-column.odcs.yaml) -- [Table with columns and partitioning](schema/table-columns-with-partition.odcs.yaml) +- [All schema types](schema/all-schema-types.md) +- [Data types](data-types/all-data-types.md) +- [Table with single column](schema/table-column.md) +- [Table with columns and partitioning](schema/table-columns-with-partition.md) ## Data quality -- [Column accuracy](quality/column-accuracy.odcs.yaml) -- [Column completeness](quality/column-completeness.odcs.yaml) -- [Column custom](quality/column-custom.odcs.yaml) -- [Column validity](quality/column-validity.odcs.yaml) +- [Column accuracy](quality/column-accuracy.md) +- [Column completeness](quality/column-completeness.md) +- [Column custom](quality/column-custom.md) +- [Column validity](quality/column-validity.md) ## Server -- [Azure server](server/azure-server.odcs.yaml) -- [Kafka server](server/kafka-server.odcs.yaml) +- [Azure server](server/azure-server.md) +- [Kafka server](server/kafka-server.md) ## Pricing This section covers pricing when you bill your customer for using this data product. ## Stakeholders -- [Stakeholders example](stakeholders/basic-four-dpo.odcs.yaml) +- [Stakeholders example](stakeholders/basic-four-dpo.md) ## Roles -- [Service and operational roles](roles/service-and-operational-roles.odcs.yaml) +- [Service and operational roles](roles/service-and-operational-roles.md) ## Service-level agreement -- [Database SLA](sla/database-table-sla.odcs.yaml) +- [Database SLA](sla/database-table-sla.md) ## Other properties Coming soon. diff --git a/mkdocs.yml b/mkdocs.yml index 0cd0fed..3e583d7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,6 +7,7 @@ plugins: - open-in-new-tab - search - social + - awesome-pages theme: name: material @@ -34,7 +35,9 @@ theme: nav: - Home: 'home.md' - Standard: 'README.md' - - Examples: 'examples/README.md' + - Examples: + - 'examples/README.md' + - '...' - Changelog: 'changelog.md' - Contributing: 'contributing.md' - Vendors: 'vendors.md' diff --git a/src/script/build_docs.sh b/src/script/build_docs.sh index 5851fa0..0d6e972 100644 --- a/src/script/build_docs.sh +++ b/src/script/build_docs.sh @@ -10,7 +10,8 @@ echo "Creating markdown file for each example" for f in docs/examples/**/*.yaml; do yaml_content=$(cat "$f") markdown_file_path="${f//odcs.yaml/md}" - header="${f//docs\/examples\//}" + file_name=$(basename "$f" .odcs.yaml) + header=$(echo "${file_name//\-/ }" | sed -e "s/\b\(.\)/\u\1/g") echo "Creating file: $markdown_file_path" content=$(cat <<-END # ${header} @@ -21,7 +22,8 @@ ${yaml_content} END ) echo "$content" > "$markdown_file_path" - escaped_header="${header//\//\\/}" + base_path="${f//docs\/examples\//}" + escaped_header="${base_path//\//\\/}" replacement_link="${escaped_header//odcs.yaml/md}" - sed -i -e "s/$escaped_header/$replacement_link/g" docs/examples/README.md + sed -i '' -e "s/$escaped_header/$replacement_link/g" docs/examples/README.md done From e09bd42ab5e3d07858e4bace9323e56999f22337 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Fri, 18 Oct 2024 15:15:41 +0800 Subject: [PATCH 90/93] Fix sed command --- src/script/build_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/build_docs.sh b/src/script/build_docs.sh index 0d6e972..bbfb0c5 100644 --- a/src/script/build_docs.sh +++ b/src/script/build_docs.sh @@ -25,5 +25,5 @@ END base_path="${f//docs\/examples\//}" escaped_header="${base_path//\//\\/}" replacement_link="${escaped_header//odcs.yaml/md}" - sed -i '' -e "s/$escaped_header/$replacement_link/g" docs/examples/README.md + sed -i -e "s/$escaped_header/$replacement_link/g" docs/examples/README.md done From 4634a59413bafa5d31040a81380faf917a0a8ec0 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Sun, 20 Oct 2024 22:55:22 +0800 Subject: [PATCH 91/93] Fix links in examples README --- docs/examples/README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/examples/README.md b/docs/examples/README.md index aab8fc0..fb75e18 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -17,46 +17,46 @@ This folder contains mainly excerpts of data contracts to illustrate specific se ## Full example -- [Full example](all/full-example.md) -- [Postgres AdventureWorks](all/postgresql-adventureworks-contract.md) +- [Full example](all/full-example.odcs.yaml) +- [Postgres AdventureWorks](all/postgresql-adventureworks-contract.odcs.yaml) ## Fundamentals -- [Table and column](fundamentals/table-column-description.md) +- [Table and column](fundamentals/table-column-description.odcs.yaml) ## Dataset and schema -- [All schema types](schema/all-schema-types.md) -- [Data types](data-types/all-data-types.md) -- [Table with single column](schema/table-column.md) -- [Table with columns and partitioning](schema/table-columns-with-partition.md) +- [All schema types](schema/all-schema-types.odcs.yaml) +- [Data types](data-types/all-data-types.odcs.yaml) +- [Table with single column](schema/table-column.odcs.yaml) +- [Table with columns and partitioning](schema/table-columns-with-partition.odcs.yaml) ## Data quality -- [Column accuracy](quality/column-accuracy.md) -- [Column completeness](quality/column-completeness.md) -- [Column custom](quality/column-custom.md) -- [Column validity](quality/column-validity.md) +- [Column accuracy](quality/column-accuracy.odcs.yaml) +- [Column completeness](quality/column-completeness.odcs.yaml) +- [Column custom](quality/column-custom.odcs.yaml) +- [Column validity](quality/column-validity.odcs.yaml) ## Server -- [Azure server](server/azure-server.md) -- [Kafka server](server/kafka-server.md) +- [Azure server](server/azure-server.odcs.yaml) +- [Kafka server](server/kafka-server.odcs.yaml) ## Pricing This section covers pricing when you bill your customer for using this data product. ## Stakeholders -- [Stakeholders example](stakeholders/basic-four-dpo.md) +- [Stakeholders example](stakeholders/basic-four-dpo.odcs.yaml) ## Roles -- [Service and operational roles](roles/service-and-operational-roles.md) +- [Service and operational roles](roles/service-and-operational-roles.odcs.yaml) ## Service-level agreement -- [Database SLA](sla/database-table-sla.md) +- [Database SLA](sla/database-table-sla.odcs.yaml) ## Other properties Coming soon. From 2d4e71de64cf814641f5689396aa3cba3575c3a6 Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Sun, 20 Oct 2024 22:57:56 +0800 Subject: [PATCH 92/93] Only deploy docs site for main branch changes --- .github/workflows/docs-site-deploy.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docs-site-deploy.yaml b/.github/workflows/docs-site-deploy.yaml index 2c93766..5f4407c 100644 --- a/.github/workflows/docs-site-deploy.yaml +++ b/.github/workflows/docs-site-deploy.yaml @@ -3,7 +3,6 @@ on: push: branches: - main - - dev permissions: contents: write jobs: From 13b2d3d62b23e97c882cad8612499f9a24a9f9bc Mon Sep 17 00:00:00 2001 From: Flook Peter Date: Sun, 20 Oct 2024 23:05:55 +0800 Subject: [PATCH 93/93] Push docs on tag changes --- .github/workflows/docs-site-deploy.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docs-site-deploy.yaml b/.github/workflows/docs-site-deploy.yaml index 5f4407c..e44ffea 100644 --- a/.github/workflows/docs-site-deploy.yaml +++ b/.github/workflows/docs-site-deploy.yaml @@ -1,6 +1,8 @@ name: docs-site-deploy on: push: + tags: + - * branches: - main permissions: