diff --git a/dbt/context/parser.py b/dbt/context/parser.py index 70687687fd0..8f25a28d957 100644 --- a/dbt/context/parser.py +++ b/dbt/context/parser.py @@ -50,23 +50,31 @@ def __init__(self, model, source_config): self.model = model self.source_config = source_config - @staticmethod - def _transform_kwargs(kwargs): - for k in ('pre_hook', 'post_hook'): - if k in kwargs: - kwargs[k.replace('_', '-')] = kwargs.pop(k) - return kwargs + def _transform_config(self, config): + for oldkey in ('pre_hook', 'post_hook'): + if oldkey in config: + newkey = oldkey.replace('_', '-') + if newkey in config: + dbt.exceptions.raise_compiler_error( + 'Invalid config, has conflicting keys "{}" and "{}"' + .format(oldkey, newkey), + self.model + ) + config[newkey] = config.pop(oldkey) + return config def __call__(self, *args, **kwargs): if len(args) == 1 and len(kwargs) == 0: opts = args[0] elif len(args) == 0 and len(kwargs) > 0: - opts = self._transform_kwargs(kwargs) + opts = kwargs else: dbt.exceptions.raise_compiler_error( "Invalid inline model config", self.model) + opts = self._transform_config(opts) + self.source_config.update_in_model_config(opts) return '' diff --git a/test/integration/014_hook_tests/configured-models/hooks.sql b/test/integration/014_hook_tests/configured-models/hooks.sql index ac5ba0c546c..21b8f0fc56b 100644 --- a/test/integration/014_hook_tests/configured-models/hooks.sql +++ b/test/integration/014_hook_tests/configured-models/hooks.sql @@ -1,7 +1,7 @@ {{ config({ - "pre-hook": "\ + "pre_hook": "\ insert into {{this.schema}}.on_model_hook (\ \"state\",\ \"target.dbname\",\ diff --git a/test/integration/014_hook_tests/error-models/hooks.sql b/test/integration/014_hook_tests/error-models/hooks.sql new file mode 100644 index 00000000000..c6e67acaf9c --- /dev/null +++ b/test/integration/014_hook_tests/error-models/hooks.sql @@ -0,0 +1,91 @@ + +{{ + config({ + "pre_hook": "\ + insert into {{this.schema}}.on_model_hook (\ + \"state\",\ + \"target.dbname\",\ + \"target.host\",\ + \"target.name\",\ + \"target.schema\",\ + \"target.type\",\ + \"target.user\",\ + \"target.pass\",\ + \"target.port\",\ + \"target.threads\",\ + \"run_started_at\",\ + \"invocation_id\"\ + ) VALUES (\ + 'start',\ + '{{ target.dbname }}',\ + '{{ target.host }}',\ + '{{ target.name }}',\ + '{{ target.schema }}',\ + '{{ target.type }}',\ + '{{ target.user }}',\ + '{{ target.pass }}',\ + {{ target.port }},\ + {{ target.threads }},\ + '{{ run_started_at }}',\ + '{{ invocation_id }}'\ + )", + "pre-hook": "\ + insert into {{this.schema}}.on_model_hook (\ + \"state\",\ + \"target.dbname\",\ + \"target.host\",\ + \"target.name\",\ + \"target.schema\",\ + \"target.type\",\ + \"target.user\",\ + \"target.pass\",\ + \"target.port\",\ + \"target.threads\",\ + \"run_started_at\",\ + \"invocation_id\"\ + ) VALUES (\ + 'start',\ + '{{ target.dbname }}',\ + '{{ target.host }}',\ + '{{ target.name }}',\ + '{{ target.schema }}',\ + '{{ target.type }}',\ + '{{ target.user }}',\ + '{{ target.pass }}',\ + {{ target.port }},\ + {{ target.threads }},\ + '{{ run_started_at }}',\ + '{{ invocation_id }}'\ + )", + "post-hook": "\ + insert into {{this.schema}}.on_model_hook (\ + \"state\",\ + \"target.dbname\",\ + \"target.host\",\ + \"target.name\",\ + \"target.schema\",\ + \"target.type\",\ + \"target.user\",\ + \"target.pass\",\ + \"target.port\",\ + \"target.threads\",\ + \"run_started_at\",\ + \"invocation_id\"\ + ) VALUES (\ + 'end',\ + '{{ target.dbname }}',\ + '{{ target.host }}',\ + '{{ target.name }}',\ + '{{ target.schema }}',\ + '{{ target.type }}',\ + '{{ target.user }}',\ + '{{ target.pass }}',\ + {{ target.port }},\ + {{ target.threads }},\ + '{{ run_started_at }}',\ + '{{ invocation_id }}'\ + )" + }) +}} + +select 3 as id diff --git a/test/integration/014_hook_tests/test_model_hooks.py b/test/integration/014_hook_tests/test_model_hooks.py index 94fe4b5113f..0233b6155fb 100644 --- a/test/integration/014_hook_tests/test_model_hooks.py +++ b/test/integration/014_hook_tests/test_model_hooks.py @@ -1,5 +1,6 @@ from nose.plugins.attrib import attr from test.integration.base import DBTIntegrationTest +from dbt.exceptions import CompilationException MODEL_PRE_HOOK = """ @@ -64,7 +65,6 @@ class BaseTestPrePost(DBTIntegrationTest): def setUp(self): - self.adapter_type = 'bigquery' DBTIntegrationTest.setUp(self) self.run_sql_file("test/integration/014_hook_tests/seed_model.sql") @@ -236,3 +236,21 @@ class TestPrePostModelHooksInConfigKwargs(TestPrePostModelHooksInConfig): def models(self): return "test/integration/014_hook_tests/kwargs-models" + + +class TestDuplicateHooksInConfigs(DBTIntegrationTest): + @property + def schema(self): + return "model_hooks_014" + + @property + def models(self): + return "test/integration/014_hook_tests/error-models" + + @attr(type='postgres') + def test_postgres_run_duplicate_hook_defs(self): + with self.assertRaises(CompilationException) as exc: + self.run_dbt(['run']) + + self.assertIn('pre_hook', str(exc.exception)) + self.assertIn('pre-hook', str(exc.exception))