Skip to content

Commit

Permalink
Decouple project creation logic from tasks CT-299 (#4981)
Browse files Browse the repository at this point in the history
  • Loading branch information
iknox-fa authored and VersusFacit committed Apr 14, 2022
1 parent 9b80df5 commit 52a18ff
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .changes/unreleased/Under the Hood-20220330-101439.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Under the Hood
body: Adds config util for ad-hoc creation of project objs or dicts
time: 2022-03-30T10:14:39.746196-05:00
custom:
Author: iknox-fa
Issue: "4808"
PR: "4981"
54 changes: 52 additions & 2 deletions core/dbt/config/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
from typing import Dict, Any
from argparse import Namespace
from typing import Any, Dict, Optional, Union
from xmlrpc.client import Boolean
from dbt.contracts.project import UserConfig

import dbt.flags as flags
from dbt.clients import yaml_helper
from dbt.config import Profile, Project, read_user_config
from dbt.config.renderer import DbtProjectYamlRenderer, ProfileRenderer
from dbt.events.functions import fire_event
from dbt.exceptions import raise_compiler_error, ValidationException
from dbt.events.types import InvalidVarsYAML
from dbt.exceptions import ValidationException, raise_compiler_error


def parse_cli_vars(var_string: str) -> Dict[str, Any]:
Expand All @@ -21,3 +27,47 @@ def parse_cli_vars(var_string: str) -> Dict[str, Any]:
except ValidationException:
fire_event(InvalidVarsYAML())
raise


def get_project_config(
project_path: str,
profile_name: str,
args: Namespace = Namespace(),
cli_vars: Optional[Dict[str, Any]] = None,
profile: Optional[Profile] = None,
user_config: Optional[UserConfig] = None,
return_dict: Boolean = True,
) -> Union[Project, Dict]:
"""Returns a project config (dict or object) from a given project path and profile name.
Args:
project_path: Path to project
profile_name: Name of profile
args: An argparse.Namespace that represents what would have been passed in on the
command line (optional)
cli_vars: A dict of any vars that would have been passed in on the command line (optional)
(see parse_cli_vars above for formatting details)
profile: A dbt.config.profile.Profile object (optional)
user_config: A dbt.contracts.project.UserConfig object (optional)
return_dict: Return a dict if true, return the full dbt.config.project.Project object if false
Returns:
A full project config
"""
# Generate a profile if not provided
if profile is None:
# Generate user_config if not provided
if user_config is None:
user_config = read_user_config(flags.PROFILES_DIR)
# Update flags
flags.set_from_args(args, user_config)
profile = Profile.render_from_args(args, ProfileRenderer(cli_vars), profile_name)
# Generate a project
project = Project.from_project_root(
project_path,
DbtProjectYamlRenderer(profile),
verify_version=bool(flags.VERSION_CHECK),
)
# Return
return project.to_project_config() if return_dict else project
1 change: 1 addition & 0 deletions test/integration/039_config_tests/models-ok/ok.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
select * from {{ ref('seed') }}
8 changes: 8 additions & 0 deletions test/integration/039_config_tests/project/dbt_project.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
config-version: 2
model-paths:
- models-ok
name: test
profile: test
test-paths: []
version: "1.0"
24 changes: 24 additions & 0 deletions test/integration/039_config_tests/project/profiles.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
config:
send_anonymous_usage_stats: false
test:
outputs:
default2:
dbname: dbt
host: localhost
pass: password
port: 5432
schema: test16486474128741104874_config_039
threads: 4
type: postgres
user: root
noaccess:
dbname: dbt
host: localhost
pass: password
port: 5432
schema: test16486474128741104874_config_039
threads: 4
type: postgres
user: noaccess
target: default2
36 changes: 34 additions & 2 deletions test/integration/039_config_tests/test_configs.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from datetime import datetime
import os
import shutil

from test.integration.base import DBTIntegrationTest, use_profile
from dbt.exceptions import CompilationException

from dbt.config.utils import get_project_config
from argparse import Namespace

class TestConfigs(DBTIntegrationTest):
@property
Expand Down Expand Up @@ -243,6 +245,7 @@ def test_postgres_warn_unused_configuration_paths(self):

self.run_dbt(['seed'])


class TestConfigIndivTests(DBTIntegrationTest):
@property
def schema(self):
Expand Down Expand Up @@ -298,7 +301,6 @@ def test_postgres_configuring_individual_tests(self):
self.assertEqual(results[1].status, 'fail')



class TestConfigGetDefault(DBTIntegrationTest):
@property
def schema(self):
Expand All @@ -316,3 +318,33 @@ def test_postgres_config_with_get_default(self):
self.assertEqual(len(results), 1)
self.assertEqual(str(results[0].status), 'error')
self.assertIn('column "default_value" does not exist', results[0].message)


class TestConfigUtils(DBTIntegrationTest):
@property
def schema(self):
return "config_039"

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

@property
def project_config(self):
project_path = os.path.dirname(os.path.realpath(__file__)) + "/project"
project_config = get_project_config(
project_path, "test", Namespace(profiles_dir=project_path)
)

# thanks yaml :(
project_config["name"] = str(project_config["name"])
project_config["version"] = str(project_config["version"])
return project_config

@use_profile("postgres")
def test_postgres_get_project_config(self):

seed_result = self.run_dbt(["seed"], expect_pass=True)
run_result = self.run_dbt(["run"], expect_pass=True)
self.assertEqual(len(seed_result), 1)
self.assertEqual(len(run_result), 1)

0 comments on commit 52a18ff

Please sign in to comment.