Repository: dbt-labs/dbt-core

Issue:
Turn on partial parser by default
Pre-req before turning on:
- [x] https://github.com/dbt-labs/dbt/issues/3810
- [x] https://github.com/dbt-labs/dbt/issues/3885
- [ ] https://github.com/dbt-labs/dbt/issues/2330#issuecomment-919798130


Discussion:
Broke this out from the over-arching story: https://github.com/dbt-labs/dbt/issues/3502
I added one more pre-req above, based on the comments I'd left in #3502.

My current feelings about these pre-reqs:
- I believe we can and should resolve #3810
- I could go any way on env vars. @gshank I'd appreciate your take on the relative complexity of those options.
- I'm leaning toward documenting #2330 as a known limitation / unsupported use of `invocation_id` + `run_started_at`

There's one more thing I'd like to do around logging when we turn on partial parsing by default: #3886

Resolving patch:
diff --git a/core/dbt/contracts/util.py b/core/dbt/contracts/util.py
--- a/core/dbt/contracts/util.py
+++ b/core/dbt/contracts/util.py
@@ -170,6 +170,12 @@ class BaseArtifactMetadata(dbtClassMixin):
     )
     env: Dict[str, str] = dataclasses.field(default_factory=get_metadata_env)
 
+    def __post_serialize__(self, dct):
+        dct = super().__post_serialize__(dct)
+        if dct['generated_at'] and dct['generated_at'].endswith('+00:00'):
+            dct['generated_at'] = dct['generated_at'].replace('+00:00', '') + "Z"
+        return dct
+
 
 def schema_version(name: str, version: int):
     def inner(cls: Type[VersionedSchema]):
diff --git a/core/dbt/flags.py b/core/dbt/flags.py
--- a/core/dbt/flags.py
+++ b/core/dbt/flags.py
@@ -41,7 +41,7 @@
     "STATIC_PARSER": True,
     "WARN_ERROR": False,
     "WRITE_JSON": True,
-    "PARTIAL_PARSE": False,
+    "PARTIAL_PARSE": True,
     "USE_COLORS": True,
     "PROFILES_DIR": DEFAULT_PROFILES_DIR,
     "DEBUG": False,
diff --git a/core/dbt/parser/manifest.py b/core/dbt/parser/manifest.py
--- a/core/dbt/parser/manifest.py
+++ b/core/dbt/parser/manifest.py
@@ -1,5 +1,6 @@
 from dataclasses import dataclass
 from dataclasses import field
+from datetime import datetime
 import os
 import traceback
 from typing import (
@@ -557,6 +558,13 @@ def read_manifest_for_partial_parse(self) -> Optional[Manifest]:
                 # different version of dbt
                 is_partial_parseable, reparse_reason = self.is_partial_parsable(manifest)
                 if is_partial_parseable:
+                    # We don't want to have stale generated_at dates
+                    manifest.metadata.generated_at = datetime.utcnow()
+                    # or invocation_ids
+                    if dbt.tracking.active_user:
+                        manifest.metadata.invocation_id = dbt.tracking.active_user.invocation_id
+                    else:
+                        manifest.metadata.invocation_id = None
                     return manifest
             except Exception as exc:
                 logger.debug(


Test patch:
diff --git a/test/rpc/test_run.py b/test/rpc/test_run.py
--- a/test/rpc/test_run.py
+++ b/test/rpc/test_run.py
@@ -73,12 +73,12 @@ def test_rpc_run_vars_compiled(
         test_kwargs={},
     )
     with querier_ctx as querier:
-        results = querier.async_wait_for_result(querier.cli_args('run --vars "{materialized_var: table}"'))
+        results = querier.async_wait_for_result(querier.cli_args('--no-partial-parse run --vars "{materialized_var: table}"'))
         assert len(results['results']) == 1
         assert results['results'][0]['node']['config']['materialized'] == 'table'
         # make sure that `--vars` doesn't update global state - if it does,
         # this run() will result in a view!
-        results = querier.async_wait_for_result(querier.cli_args('run'))
+        results = querier.async_wait_for_result(querier.cli_args('--no-partial-parse run'))
         assert len(results['results']) == 1
         assert results['results'][0]['node']['config']['materialized'] == 'view'