Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop trying to parse deleted schema files #9722

Merged
merged 4 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20240301-135536.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: Fix partial parsing `KeyError` on deleted schema files
time: 2024-03-01T13:55:36.533176-08:00
custom:
Author: QMalcolm
Issue: "8860"
7 changes: 6 additions & 1 deletion core/dbt/parser/partial.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@
if (
file_id not in self.project_parser_files[project_name][parser_name]
and file_id not in self.file_diff["deleted"]
and file_id not in self.file_diff["deleted_schema_files"]
):
self.project_parser_files[project_name][parser_name].append(file_id)

Expand Down Expand Up @@ -467,7 +468,11 @@

def _schedule_for_parsing(self, dict_key: str, element, name, delete: Callable) -> None:
file_id = element.file_id
if file_id in self.saved_files and file_id not in self.file_diff["deleted"]:
if (

Check warning on line 471 in core/dbt/parser/partial.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/partial.py#L471

Added line #L471 was not covered by tests
file_id in self.saved_files
and file_id not in self.file_diff["deleted"]
and file_id not in self.file_diff["deleted_schema_files"]
):
schema_file = self.saved_files[file_id]
elements = []
assert isinstance(schema_file, SchemaSourceFile)
Expand Down
54 changes: 54 additions & 0 deletions tests/functional/partial_parsing/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,60 @@
agg_time_dimension: created_at
"""

people_sl_yml = """
version: 2

semantic_models:
- name: semantic_people
model: ref('people')
dimensions:
- name: favorite_color
type: categorical
- name: created_at
type: TIME
type_params:
time_granularity: day
measures:
- name: years_tenure
agg: SUM
expr: tenure
- name: people
agg: count
expr: id
entities:
- name: id
type: primary
defaults:
agg_time_dimension: created_at

metrics:

- name: number_of_people
description: Total count of people
label: "Number of people"
type: simple
type_params:
measure: people
meta:
my_meta: 'testing'

- name: collective_tenure
description: Total number of years of team experience
label: "Collective tenure"
type: simple
type_params:
measure:
name: years_tenure
filter: "{{ Dimension('id__loves_dbt') }} is true"

- name: average_tenure
label: Average Tenure
type: ratio
type_params:
numerator: collective_tenure
denominator: number_of_people
"""

env_var_metrics_yml = """

metrics:
Expand Down
31 changes: 30 additions & 1 deletion tests/functional/partial_parsing/test_pp_metrics.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest

from dbt.tests.util import run_dbt, write_file, get_manifest
from dbt.cli.main import dbtRunner
from dbt.contracts.graph.manifest import Manifest
from dbt.tests.util import run_dbt, rm_file, write_file, get_manifest
from tests.functional.partial_parsing.fixtures import (
people_sql,
metricflow_time_spine_sql,
Expand All @@ -9,6 +11,7 @@
people_metrics2_yml,
metric_model_a_sql,
people_metrics3_yml,
people_sl_yml,
)

from dbt.exceptions import CompilationError
Expand Down Expand Up @@ -84,3 +87,29 @@ def test_metrics(self, project):
# We use "parse" here and not "run" because we're checking that the CompilationError
# occurs at parse time, not compilation
results = run_dbt(["parse"])


class TestDeleteFileWithMetricsAndSemanticModels:
@pytest.fixture(scope="class")
def models(self):
return {
"people.sql": people_sql,
"metricflow_time_spine.sql": metricflow_time_spine_sql,
"people_sl.yml": people_sl_yml,
}

def test_metrics(self, project):
# Initial parsing
runner = dbtRunner()
result = runner.invoke(["parse"])
assert result.success
manifest = result.result
assert isinstance(manifest, Manifest)
assert len(manifest.metrics) == 3

# Remove metric file
rm_file(project.project_root, "models", "people_sl.yml")

# Rerun parse, shouldn't fail
result = runner.invoke(["parse"])
assert result.exception is None, result.exception
Loading