|
| 1 | +import json |
| 2 | +import os |
| 3 | + |
1 | 4 | import pytest |
2 | 5 |
|
3 | 6 | from dbt.artifacts.schemas.catalog import CatalogArtifact |
4 | 7 | from dbt.tests.adapter.catalog import files |
5 | 8 | 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 |
7 | 10 |
|
8 | 11 |
|
9 | 12 | class TestRelationTypes(CatalogRelationTypes): |
@@ -51,3 +54,103 @@ def test_relation_types_populate_correctly( |
51 | 54 | assert node_name in docs.nodes |
52 | 55 | node = docs.nodes[node_name] |
53 | 56 | 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