Skip to content

Commit 5c16be4

Browse files
committed
✨ feat: secondary database in catalog tests
1 parent e2f4bf3 commit 5c16be4

1 file changed

Lines changed: 104 additions & 1 deletion

File tree

tests/functional/adapter/dbt/test_catalog.py

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import json
2+
import os
3+
14
import pytest
25

36
from dbt.artifacts.schemas.catalog import CatalogArtifact
47
from dbt.tests.adapter.catalog import files
58
from dbt.tests.adapter.catalog.relation_types import CatalogRelationTypes
6-
from dbt.tests.util import run_dbt
9+
from dbt.tests.util import get_connection, run_dbt
710

811

912
class TestRelationTypes(CatalogRelationTypes):
@@ -51,3 +54,103 @@ def test_relation_types_populate_correctly(
5154
assert node_name in docs.nodes
5255
node = docs.nodes[node_name]
5356
assert node.metadata.type == relation_type
57+
58+
59+
class TestCatalogAcrossDatabases:
60+
SECONDARY_DATABASE = "secondary_db"
61+
62+
@pytest.fixture(scope="class")
63+
def project_config_update(self):
64+
return {
65+
"vars": {
66+
"test_second_database": self.SECONDARY_DATABASE,
67+
},
68+
}
69+
70+
@pytest.fixture(scope="class")
71+
def schema_yml(self):
72+
return """
73+
version: 2
74+
75+
models:
76+
- name: default_db_model
77+
description: model in the profile/default database
78+
columns:
79+
- name: id
80+
description: id column
81+
82+
- name: other_db_model
83+
description: model in a non-default database
84+
columns:
85+
- name: id
86+
description: id column
87+
"""
88+
89+
@pytest.fixture(scope="class")
90+
def models(self, schema_yml):
91+
return {
92+
"default_db_model.sql": "select 1 as id",
93+
"other_db_model.sql": """
94+
{{ config(database=var('test_second_database')) }}
95+
select 2 as id
96+
""",
97+
"schema.yml": schema_yml,
98+
}
99+
100+
def create_secondary_db(self, project):
101+
create_sql = """
102+
DECLARE @col NVARCHAR(256)
103+
SET @col = (SELECT CONVERT(varchar(256), SERVERPROPERTY('collation')));
104+
105+
IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = '{database}')
106+
BEGIN
107+
EXEC('CREATE DATABASE [{database}] COLLATE ' + @col)
108+
END
109+
"""
110+
with get_connection(project.adapter):
111+
project.adapter.execute(
112+
create_sql.format(database=self.SECONDARY_DATABASE),
113+
fetch=True,
114+
)
115+
116+
def cleanup_secondary_database(self, project):
117+
drop_sql = """
118+
USE [master]
119+
120+
IF EXISTS (SELECT * FROM sys.databases WHERE name = '{database}')
121+
BEGIN
122+
ALTER DATABASE [{database}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
123+
DROP DATABASE [{database}]
124+
END
125+
"""
126+
with get_connection(project.adapter):
127+
project.adapter.execute(
128+
drop_sql.format(database=self.SECONDARY_DATABASE),
129+
fetch=True,
130+
)
131+
132+
def test_docs_generate_includes_non_default_database(self, project):
133+
self.create_secondary_db(project)
134+
try:
135+
run_dbt(["run"])
136+
run_dbt(["docs", "generate"])
137+
138+
catalog_path = os.path.join(project.project_root, "target", "catalog.json")
139+
with open(catalog_path) as fp:
140+
catalog = json.load(fp)
141+
142+
nodes = catalog["nodes"]
143+
144+
default_node = nodes["model.test.default_db_model"]
145+
other_node = nodes["model.test.other_db_model"]
146+
147+
assert default_node["metadata"]["name"] == "default_db_model"
148+
assert other_node["metadata"]["name"] == "other_db_model"
149+
150+
assert default_node["metadata"]["database"] != other_node["metadata"]["database"]
151+
assert other_node["metadata"]["database"] == self.SECONDARY_DATABASE
152+
153+
assert "id" in default_node["columns"]
154+
assert "id" in other_node["columns"]
155+
finally:
156+
self.cleanup_secondary_database(project)

0 commit comments

Comments
 (0)