Skip to content

Commit

Permalink
[#4012] Performance: Use child_map to find tests for nodes in resolve…
Browse files Browse the repository at this point in the history
…_graph (#4022)
  • Loading branch information
gshank authored Oct 13, 2021
1 parent 79aa136 commit fd7c95d
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- Fix multiple disabled nodes ([#4013](https://github.com/dbt-labs/dbt/issues/4013), [#4018](https://github.com/dbt-labs/dbt/pull/4018))
- Fix multiple partial parsing errors ([#3996](https://github.com/dbt-labs/dbt/issues/3006), [#4020](https://github.com/dbt-labs/dbt/pull/4018))
- Return an error instead of a warning when runing with `--warn-error` and no models are selected ([#4006](https://github.com/dbt-labs/dbt/issues/4006), [#4019](https://github.com/dbt-labs/dbt/pull/4019))
- Performance: Use child_map to find tests for nodes in resolve_graph ([#4012](https://github.com/dbt-labs/dbt/issues/4012), [#4022](https://github.com/dbt-labs/dbt/pull/4022))

### Under the hood

Expand Down
15 changes: 9 additions & 6 deletions core/dbt/compilation.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,13 @@ def _get_tests_for_node(manifest: Manifest, unique_id: UniqueID) -> List[UniqueI
""" Get a list of tests that depend on the node with the
provided unique id """

return [
node.unique_id
for _, node in manifest.nodes.items()
if node.resource_type == NodeType.Test and
unique_id in node.depends_on_nodes
]
tests = []
if unique_id in manifest.child_map:
for child_unique_id in manifest.child_map[unique_id]:
if child_unique_id.startswith('test.'):
tests.append(child_unique_id)

return tests


class Linker:
Expand Down Expand Up @@ -430,6 +431,8 @@ def link_graph(self, linker: Linker, manifest: Manifest):
if cycle:
raise RuntimeError("Found a cycle: {}".format(cycle))

manifest.build_parent_and_child_maps()

self.resolve_graph(linker, manifest)

def resolve_graph(self, linker: Linker, manifest: Manifest) -> None:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
select 1 as id
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
select * from {{ ref('model_b') }}
41 changes: 41 additions & 0 deletions test/integration/069_build_test/models-interdependent/schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
version: 2

models:
- name: model_a
columns:
- name: id
tests:
- unique
- not_null
- relationships:
to: ref('model_b')
field: id
- relationships:
to: ref('model_c')
field: id

- name: model_b
columns:
- name: id
tests:
- unique
- not_null
- relationships:
to: ref('model_a')
field: id
- relationships:
to: ref('model_c')
field: id

- name: model_c
columns:
- name: id
tests:
- unique
- not_null
- relationships:
to: ref('model_a')
field: id
- relationships:
to: ref('model_b')
field: id
1 change: 1 addition & 0 deletions test/integration/069_build_test/test-files/model_b.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
select * from {{ ref('model_a') }}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
select null from {{ ref('model_a') }}
41 changes: 40 additions & 1 deletion test/integration/069_build_test/test_build.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from test.integration.base import DBTIntegrationTest, use_profile
from test.integration.base import DBTIntegrationTest, use_profile, normalize
import yaml
import shutil
import os


class TestBuildBase(DBTIntegrationTest):
Expand Down Expand Up @@ -79,3 +81,40 @@ def test__postgres_circular_relationship_test_success(self):
actual = [r.status for r in results]
expected = ['success']*7 + ['pass']*2
self.assertEqual(sorted(actual), sorted(expected))

class TestInterdependentModels(TestBuildBase):

@property
def project_config(self):
return {
"config-version": 2,
"snapshot-paths": ["snapshots-none"],
"seeds": {
"quote_columns": False,
},
}

@property
def models(self):
return "models-interdependent"

def tearDown(self):
if os.path.exists(normalize('models-interdependent/model_b.sql')):
os.remove(normalize('models-interdependent/model_b.sql'))


@use_profile("postgres")
def test__postgres_interdependent_models(self):
# check that basic build works
shutil.copyfile('test-files/model_b.sql', 'models-interdependent/model_b.sql')
results = self.build()
self.assertEqual(len(results), 16)

# return null from model_b
shutil.copyfile('test-files/model_b_null.sql', 'models-interdependent/model_b.sql')
results = self.build(expect_pass=False)
self.assertEqual(len(results), 16)
actual = [str(r.status) for r in results]
expected = ['error']*4 + ['skipped']*7 + ['pass']*2 + ['success']*3
self.assertEqual(sorted(actual), sorted(expected))

0 comments on commit fd7c95d

Please sign in to comment.