diff --git a/schemas/dbt_project.json b/schemas/dbt_project.json index d8f7258..e848926 100644 --- a/schemas/dbt_project.json +++ b/schemas/dbt_project.json @@ -163,6 +163,18 @@ "type": "string" } }, + "contract": { + "type": "object", + "required": [ + "enforced" + ], + "properties": { + "enforced": { + "$ref": "#/$defs/boolean_or_jinja_string", + "default": "true" + } + } + }, "empty_directory": { "type": "null" }, @@ -254,6 +266,9 @@ "$ref": "#/$defs/boolean_or_jinja_string", "default": false }, + "+contract": { + "$ref": "#/$defs/contract" + }, "+database": { "$ref": "#/$defs/database" }, @@ -309,6 +324,9 @@ "$ref": "#/$defs/boolean_or_jinja_string", "default": false }, + "contract": { + "$ref": "#/$defs/contract" + }, "database": { "$ref": "#/$defs/database" }, diff --git a/schemas/dbt_yml_files.json b/schemas/dbt_yml_files.json index 878c288..01e2739 100644 --- a/schemas/dbt_yml_files.json +++ b/schemas/dbt_yml_files.json @@ -115,6 +115,32 @@ } } }, + "groups": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "owner"], + "properties": { + "name": { + "type": "string" + }, + "owner": { + "type": "object", + "minProperties": 1, + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, "macros": { "type": "array", "items": { @@ -183,6 +209,20 @@ ] }, "properties": { + "config": { + "type": "object", + "properties": { + "enabled": { + "$ref": "#/$defs/boolean_or_jinja_string" + }, + "treat_null_values_as_zero": { + "$ref": "#/$defs/boolean_or_jinja_string" + }, + "group": { + "type": "string" + } + } + }, "calculation_method": { "type": "string" }, @@ -246,6 +286,10 @@ "name": { "type": "string" }, + "access": { + "type": "string", + "enum": ["private", "protected", "public"] + }, "columns": { "type": "array", "items": { @@ -253,54 +297,10 @@ } }, "config": { - "type": "object", - "properties": { - "grant_access_to": { - "title": "Authorized views", - "type": "array", - "description": "Configuration, specific to BigQuery adapter, used to setup authorized views.", - "items": { - "type": "object", - "required": ["database", "project"], - "properties": { - "database": { - "type": "string" - }, - "project": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "hours_to_expiration": { - "type": "number", - "description": "Configuration specific to BigQuery adapter used to set an expiration delay (in hours) to a table." - }, - "kms_key_name": { - "type": "string", - "description": "Configuration of the KMS key name, specific to BigQuery adapter.", - "pattern": "projects/[a-zA-Z0-9_-]*/locations/[a-zA-Z0-9_-]*/keyRings/.*/cryptoKeys/.*" - }, - "labels": { - "title": "Label configs", - "type": "object", - "description": "Configuration specific to BigQuery adapter used to add labels and tags to tables/views created by dbt.", - "patternProperties": { - "^[a-z][a-z0-9_-]{0,62}$": { - "type": "string", - "pattern": "^[a-z0-9_-]{0,63}$" - } - }, - "additionalProperties": false - }, - "materialized": { - "type": "string" - }, - "sql_header": { - "type": "string" - } - } + "$ref": "#/$defs/model_configs" + }, + "constraints": { + "$ref": "#/$defs/constraints" }, "description": { "type": "string" @@ -313,6 +313,12 @@ } } }, + "group": { + "type": "string" + }, + "latest_version": { + "type": "number" + }, "meta": { "type": "object" }, @@ -321,6 +327,34 @@ "items": { "$ref": "#/$defs/tests" } + }, + "versions": { + "type": "array", + "items": { + "type": "object", + "required": ["v"], + "properties": { + "v": { + "type": "number" + }, + "config": { + "$ref": "#/$defs/model_configs" + }, + "columns": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/$defs/include_exclude" + }, + { + "$ref": "#/$defs/column_properties" + } + ] + } + } + } + } } }, "additionalProperties": false @@ -634,6 +668,9 @@ "name": { "type": "string" }, + "constraints": { + "$ref": "#/$defs/constraints" + }, "data_type": { "type": "string" }, @@ -666,6 +703,33 @@ }, "additionalProperties": false }, + "constraints": { + "type": "array", + "items": { + "type": "object", + "required": ["type"], + "properties": { + "columns": { + "$ref": "#/$defs/string_or_array_of_strings" + }, + "expression": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "warn_unenforced": { + "$ref": "#/$defs/boolean_or_jinja_string" + }, + "warn_unsupported": { + "$ref": "#/$defs/boolean_or_jinja_string" + } + } + } + }, "freshness_definition": { "default": { "warn_after": { @@ -712,10 +776,79 @@ }, "additionalProperties": false }, + "include_exclude": { + "type": "object", + "properties": { + "include": { + "$ref": "#/$defs/string_or_array_of_strings" + }, + "exclude": { + "$ref": "#/$defs/string_or_array_of_strings" + } + } + }, "jinja_string": { "type": "string", "pattern": "\\{\\{.*\\}\\}" }, + "model_configs": { + "type": "object", + "properties": { + "contract": { + "type": "object", + "properties": { + "enforced": { + "$ref": "#/$defs/boolean_or_jinja_string" + } + } + }, + "grant_access_to": { + "title": "Authorized views", + "type": "array", + "description": "Configuration, specific to BigQuery adapter, used to setup authorized views.", + "items": { + "type": "object", + "required": ["database", "project"], + "properties": { + "database": { + "type": "string" + }, + "project": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "hours_to_expiration": { + "type": "number", + "description": "Configuration specific to BigQuery adapter used to set an expiration delay (in hours) to a table." + }, + "kms_key_name": { + "type": "string", + "description": "Configuration of the KMS key name, specific to BigQuery adapter.", + "pattern": "projects/[a-zA-Z0-9_-]*/locations/[a-zA-Z0-9_-]*/keyRings/.*/cryptoKeys/.*" + }, + "labels": { + "title": "Label configs", + "type": "object", + "description": "Configuration specific to BigQuery adapter used to add labels and tags to tables/views created by dbt.", + "patternProperties": { + "^[a-z][a-z0-9_-]{0,62}$": { + "type": "string", + "pattern": "^[a-z0-9_-]{0,63}$" + } + }, + "additionalProperties": false + }, + "materialized": { + "type": "string" + }, + "sql_header": { + "type": "string" + } + } + }, "number_or_jinja_string": { "oneOf": [ { diff --git a/tests/valid/dbt_project.yml b/tests/valid/dbt_project.yml index 4359074..d1f73c5 100644 --- a/tests/valid/dbt_project.yml +++ b/tests/valid/dbt_project.yml @@ -39,6 +39,10 @@ models: # same key without the plus materialized: table empty_subdirectory: + contracted_models: + +contract: + enforced: true + test_bq: +labels: key: val diff --git a/tests/valid/schema.yml b/tests/valid/schema.yml index 2a31015..277f4f3 100644 --- a/tests/valid/schema.yml +++ b/tests/valid/schema.yml @@ -19,6 +19,51 @@ models: - unique - not_null + - name: my_contracted_dbt_model + description: "A dbt model with contracts" + access: public + group: analytics + latest_version: 2 + config: + contract: + enforced: true + columns: + - name: id + description: "The primary key for this table" + data_type: int + constraints: + - type: not_null + - type: unique + - type: check + expression: (id > 0) + tests: + - unique + - not_null + versions: + - v: 2 + columns: + - include: '*' + exclude: country_name + - name: id # included in addition the '*' set. if id were in the '*' set -> override it + description: This is the primary key + data_type: float + - v: 1 + config: + alias: dim_customers + + - name: my_model_level_contract_model + config: + contract: + enforced: true + constraints: + - type: check + expression: (id > 0) + - type: primary_key + columns: [ id ] + - type: unique + columns: [ color, date_day ] + name: strange_uniqueness_requirement + snapshots: - name: snapshot_name @@ -28,6 +73,13 @@ snapshots: description: cool column, eh? +# model groups + +groups: + - name: analytics + owner: + name: dave + metrics: - name: new_customers label: New Customers marked 'paying' @@ -61,4 +113,4 @@ metrics: description: "The number of paid customers using the product" calculation_method: derived - expression: "{{ metric('new_customers') }} * 2" \ No newline at end of file + expression: "{{ metric('new_customers') }} * 2"