From 7917bd5033f18a9accc262d2f242e4896d63068f Mon Sep 17 00:00:00 2001 From: Michelle Ark Date: Fri, 2 Jun 2023 13:16:14 -0700 Subject: [PATCH] add project_name to manifest metadata (#7754) --- .../unreleased/Features-20230601-132223.yaml | 6 + core/dbt/config/runtime.py | 6 +- core/dbt/contracts/graph/manifest.py | 8 +- schemas/dbt/manifest/v10.json | 340 ++++++++---------- tests/functional/artifacts/test_artifacts.py | 1 + 5 files changed, 165 insertions(+), 196 deletions(-) create mode 100644 .changes/unreleased/Features-20230601-132223.yaml diff --git a/.changes/unreleased/Features-20230601-132223.yaml b/.changes/unreleased/Features-20230601-132223.yaml new file mode 100644 index 00000000000..e4501bd8581 --- /dev/null +++ b/.changes/unreleased/Features-20230601-132223.yaml @@ -0,0 +1,6 @@ +kind: Features +body: add project_name to manifest metadata +time: 2023-06-01T13:22:23.259448-04:00 +custom: + Author: michelleark jtcohen6 + Issue: "7752" diff --git a/core/dbt/config/runtime.py b/core/dbt/config/runtime.py index d58a9009922..2f95ab6d664 100644 --- a/core/dbt/config/runtime.py +++ b/core/dbt/config/runtime.py @@ -271,7 +271,11 @@ def from_args(cls, args: Any) -> "RuntimeConfig": ) def get_metadata(self) -> ManifestMetadata: - return ManifestMetadata(project_id=self.hashed_name(), adapter_type=self.credentials.type) + return ManifestMetadata( + project_name=self.project_name, + project_id=self.hashed_name(), + adapter_type=self.credentials.type, + ) def _get_v2_config_paths( self, diff --git a/core/dbt/contracts/graph/manifest.py b/core/dbt/contracts/graph/manifest.py index 401d6924f1b..3f4f3adec2c 100644 --- a/core/dbt/contracts/graph/manifest.py +++ b/core/dbt/contracts/graph/manifest.py @@ -368,10 +368,16 @@ class ManifestMetadata(BaseArtifactMetadata): dbt_schema_version: str = field( default_factory=lambda: str(WritableManifest.dbt_schema_version) ) + project_name: Optional[str] = field( + default=None, + metadata={ + "description": "Name of the root project", + }, + ) project_id: Optional[str] = field( default=None, metadata={ - "description": "A unique identifier for the project", + "description": "A unique identifier for the project, hashed from the project name", }, ) user_id: Optional[UUID] = field( diff --git a/schemas/dbt/manifest/v10.json b/schemas/dbt/manifest/v10.json index 7ea2441e02b..3b6773d66a6 100644 --- a/schemas/dbt/manifest/v10.json +++ b/schemas/dbt/manifest/v10.json @@ -224,12 +224,12 @@ }, "dbt_version": { "type": "string", - "default": "1.6.0a1" + "default": "1.6.0b2" }, "generated_at": { "type": "string", "format": "date-time", - "default": "2023-04-19T14:31:46.624262Z" + "default": "2023-06-01T17:10:44.803525Z" }, "invocation_id": { "oneOf": [ @@ -240,7 +240,7 @@ "type": "null" } ], - "default": "6bf8103b-748b-4b8c-b684-ec7814ec77ca" + "default": "2cd4fe5a-501b-422f-a628-80b34230967b" }, "env": { "type": "object", @@ -249,6 +249,17 @@ }, "default": {} }, + "project_name": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Name of the root project" + }, "project_id": { "oneOf": [ { @@ -258,7 +269,7 @@ "type": "null" } ], - "description": "A unique identifier for the project" + "description": "A unique identifier for the project, hashed from the project name" }, "user_id": { "oneOf": [ @@ -459,7 +470,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.630888 + "default": 1685639444.805417 }, "config_call_dict": { "type": "object", @@ -1171,7 +1182,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.637792 + "default": 1685639444.807345 }, "config_call_dict": { "type": "object", @@ -1559,7 +1570,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.642067 + "default": 1685639444.807956 }, "config_call_dict": { "type": "object", @@ -1835,7 +1846,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.645828 + "default": 1685639444.8085592 }, "config_call_dict": { "type": "object", @@ -1981,7 +1992,18 @@ "deprecation_date": { "oneOf": [ { - "type": "string" + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ] + }, + "state_relation": { + "oneOf": [ + { + "$ref": "#/definitions/StateRelation" }, { "type": "null" @@ -1990,7 +2012,7 @@ } }, "additionalProperties": false, - "description": "ModelNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = , _event_status: Dict[str, Any] = , tags: List[str] = , description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = , meta: Dict[str, Any] = , group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = , patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = , created_at: float = , config_call_dict: Dict[str, Any] = , relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = , sources: List[List[str]] = , metrics: List[List[str]] = , depends_on: dbt.contracts.graph.nodes.DependsOn = , compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = , _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = , access: dbt.node_types.AccessType = , constraints: List[dbt.contracts.graph.nodes.ModelLevelConstraint] = , version: Union[str, float, NoneType] = None, latest_version: Union[str, float, NoneType] = None)" + "description": "ModelNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = , _event_status: Dict[str, Any] = , tags: List[str] = , description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = , meta: Dict[str, Any] = , group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = , patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = , created_at: float = , config_call_dict: Dict[str, Any] = , relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = , sources: List[List[str]] = , metrics: List[List[str]] = , depends_on: dbt.contracts.graph.nodes.DependsOn = , compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = , _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = , access: dbt.node_types.AccessType = , constraints: List[dbt.contracts.graph.nodes.ModelLevelConstraint] = , version: Union[str, float, NoneType] = None, latest_version: Union[str, float, NoneType] = None, deprecation_date: Optional[datetime.datetime] = None, state_relation: Optional[dbt.contracts.graph.nodes.StateRelation] = None)" }, "ModelLevelConstraint": { "type": "object", @@ -2048,6 +2070,33 @@ "additionalProperties": false, "description": "ModelLevelConstraint(type: dbt.contracts.graph.nodes.ConstraintType, name: Optional[str] = None, expression: Optional[str] = None, warn_unenforced: bool = True, warn_unsupported: bool = True, columns: List[str] = )" }, + "StateRelation": { + "type": "object", + "required": [ + "alias", + "schema" + ], + "properties": { + "alias": { + "type": "string" + }, + "database": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "schema": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "StateRelation(alias: str, database: Optional[str], schema: str)" + }, "RPCNode": { "type": "object", "required": [ @@ -2209,7 +2258,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.648939 + "default": 1685639444.809459 }, "config_call_dict": { "type": "object", @@ -2475,7 +2524,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.651103 + "default": 1685639444.810038 }, "config_call_dict": { "type": "object", @@ -2734,7 +2783,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.653884 + "default": 1685639444.810735 }, "config_call_dict": { "type": "object", @@ -3030,7 +3079,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.661021 + "default": 1685639444.8118432 }, "config_call_dict": { "type": "object", @@ -3130,10 +3179,20 @@ "enforced": false, "checksum": null } + }, + "state_relation": { + "oneOf": [ + { + "$ref": "#/definitions/StateRelation" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false, - "description": "SnapshotNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SnapshotConfig, _event_status: Dict[str, Any] = , tags: List[str] = , description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = , meta: Dict[str, Any] = , group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = , patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = , created_at: float = , config_call_dict: Dict[str, Any] = , relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = , sources: List[List[str]] = , metrics: List[List[str]] = , depends_on: dbt.contracts.graph.nodes.DependsOn = , compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = , _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = )" + "description": "SnapshotNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SnapshotConfig, _event_status: Dict[str, Any] = , tags: List[str] = , description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = , meta: Dict[str, Any] = , group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = , patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = , created_at: float = , config_call_dict: Dict[str, Any] = , relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = , sources: List[List[str]] = , metrics: List[List[str]] = , depends_on: dbt.contracts.graph.nodes.DependsOn = , compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = , _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = , state_relation: Optional[dbt.contracts.graph.nodes.StateRelation] = None)" }, "SnapshotConfig": { "type": "object", @@ -3518,7 +3577,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.667295 + "default": 1685639444.812869 }, "config_call_dict": { "type": "object", @@ -3553,10 +3612,20 @@ "default": { "macros": [] } + }, + "state_relation": { + "oneOf": [ + { + "$ref": "#/definitions/StateRelation" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false, - "description": "SeedNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = , _event_status: Dict[str, Any] = , tags: List[str] = , description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = , meta: Dict[str, Any] = , group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = , patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = , created_at: float = , config_call_dict: Dict[str, Any] = , relation_name: Optional[str] = None, raw_code: str = '', root_path: Optional[str] = None, depends_on: dbt.contracts.graph.nodes.MacroDependsOn = )" + "description": "SeedNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = , _event_status: Dict[str, Any] = , tags: List[str] = , description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = , meta: Dict[str, Any] = , group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = , patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = , created_at: float = , config_call_dict: Dict[str, Any] = , relation_name: Optional[str] = None, raw_code: str = '', root_path: Optional[str] = None, depends_on: dbt.contracts.graph.nodes.MacroDependsOn = , state_relation: Optional[dbt.contracts.graph.nodes.StateRelation] = None)" }, "SeedConfig": { "type": "object", @@ -3920,7 +3989,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.670914 + "default": 1685639444.814112 } }, "additionalProperties": false, @@ -4020,138 +4089,6 @@ "additionalProperties": false, "description": "FreshnessThreshold(warn_after: Optional[dbt.contracts.graph.unparsed.Time] = , error_after: Optional[dbt.contracts.graph.unparsed.Time] = , filter: Optional[str] = None)" }, - "FreshnessMetadata": { - "type": "object", - "required": [], - "properties": { - "dbt_schema_version": { - "type": "string", - "default": "https://schemas.getdbt.com/dbt/sources/v3.json" - }, - "dbt_version": { - "type": "string", - "default": "1.6.0a1" - }, - "generated_at": { - "type": "string", - "format": "date-time", - "default": "2023-04-19T14:31:46.615335Z" - }, - "invocation_id": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": "6bf8103b-748b-4b8c-b684-ec7814ec77ca" - }, - "env": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "default": {} - } - }, - "additionalProperties": false, - "description": "FreshnessMetadata(dbt_schema_version: str = , dbt_version: str = '1.6.0a1', generated_at: datetime.datetime = , invocation_id: Optional[str] = , env: Dict[str, str] = )" - }, - "SourceFreshnessRuntimeError": { - "type": "object", - "required": [ - "unique_id", - "status" - ], - "properties": { - "unique_id": { - "type": "string" - }, - "error": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - }, - { - "type": "null" - } - ] - }, - "status": { - "type": "string", - "enum": [ - "runtime error" - ] - } - }, - "additionalProperties": false, - "description": "SourceFreshnessRuntimeError(unique_id: str, error: Union[str, int, NoneType], status: dbt.contracts.results.FreshnessErrorEnum)" - }, - "SourceFreshnessOutput": { - "type": "object", - "required": [ - "unique_id", - "max_loaded_at", - "snapshotted_at", - "max_loaded_at_time_ago_in_s", - "status", - "criteria", - "adapter_response", - "timing", - "thread_id", - "execution_time" - ], - "properties": { - "unique_id": { - "type": "string" - }, - "max_loaded_at": { - "type": "string", - "format": "date-time" - }, - "snapshotted_at": { - "type": "string", - "format": "date-time" - }, - "max_loaded_at_time_ago_in_s": { - "type": "number" - }, - "status": { - "type": "string", - "enum": [ - "pass", - "warn", - "error", - "runtime error" - ] - }, - "criteria": { - "$ref": "#/definitions/FreshnessThreshold" - }, - "adapter_response": { - "type": "object" - }, - "timing": { - "type": "array", - "items": { - "$ref": "#/definitions/TimingInfo" - } - }, - "thread_id": { - "type": "string" - }, - "execution_time": { - "type": "number" - } - }, - "additionalProperties": false, - "description": "SourceFreshnessOutput(unique_id: str, max_loaded_at: datetime.datetime, snapshotted_at: datetime.datetime, max_loaded_at_time_ago_in_s: float, status: dbt.contracts.results.FreshnessStatus, criteria: dbt.contracts.graph.unparsed.FreshnessThreshold, adapter_response: Dict[str, Any], timing: List[dbt.contracts.results.TimingInfo], thread_id: str, execution_time: float)" - }, "Time": { "type": "object", "required": [], @@ -4185,41 +4122,6 @@ "additionalProperties": false, "description": "Time(count: Optional[int] = None, period: Optional[dbt.contracts.graph.unparsed.TimePeriod] = None)" }, - "TimingInfo": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - }, - "started_at": { - "oneOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "null" - } - ] - }, - "completed_at": { - "oneOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false, - "description": "TimingInfo(name: str, started_at: Optional[datetime.datetime] = None, completed_at: Optional[datetime.datetime] = None)" - }, "ExternalTable": { "type": "object", "required": [], @@ -4399,7 +4301,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.671911 + "default": 1685639444.814394 }, "supported_languages": { "oneOf": [ @@ -4640,7 +4542,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.6743622 + "default": 1685639444.815081 } }, "additionalProperties": false, @@ -4861,7 +4763,7 @@ }, "created_at": { "type": "number", - "default": 1681914706.6769578 + "default": 1685639444.8157508 }, "group": { "oneOf": [ @@ -5015,6 +4917,36 @@ "relation_name": { "type": "string" }, + "database": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "schema": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "identifier": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, "version": { "oneOf": [ { @@ -5028,11 +4960,20 @@ } ] }, - "is_latest_version": { - "type": "boolean", - "default": false + "latest_version": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "null" + } + ] }, - "public_dependencies": { + "public_node_dependencies": { "type": "array", "items": { "type": "string" @@ -5042,11 +4983,22 @@ "generated_at": { "type": "string", "format": "date-time", - "default": "2023-04-19T14:31:46.679989Z" + "default": "2023-06-01T17:10:44.816336Z" + }, + "deprecation_date": { + "oneOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false, - "description": "PublicModel(name: str, package_name: str, unique_id: str, relation_name: str, version: Union[str, float, NoneType] = None, is_latest_version: bool = False, public_dependencies: List[str] = , generated_at: datetime.datetime = )" + "description": "Used to represent cross-project models" } }, "$schema": "http://json-schema.org/draft-07/schema#", diff --git a/tests/functional/artifacts/test_artifacts.py b/tests/functional/artifacts/test_artifacts.py index 1ccc4c75309..df272f3a2f7 100644 --- a/tests/functional/artifacts/test_artifacts.py +++ b/tests/functional/artifacts/test_artifacts.py @@ -484,6 +484,7 @@ def verify_manifest(project, expected_manifest, start_time, manifest_schema_path "project_id" in metadata and metadata["project_id"] == "098f6bcd4621d373cade4e832627b4f6" ) + assert "project_name" in metadata and metadata["project_name"] == "test" assert ( "send_anonymous_usage_stats" in metadata and metadata["send_anonymous_usage_stats"] is False