diff --git a/core/dbt/exceptions.py b/core/dbt/exceptions.py index a2034ac6f7e..d3dd355f647 100644 --- a/core/dbt/exceptions.py +++ b/core/dbt/exceptions.py @@ -652,10 +652,16 @@ def raise_not_implemented(msg): raise NotImplementedException(msg) -def warn_or_error(msg, node=None, log_fmt=None): +_REPEAT_MESSAGE_CACHE = set() + + +def warn_or_error(msg, node=None, log_fmt=None, repeat=True): if dbt.flags.WARN_ERROR: raise_compiler_error(msg, node) else: + if not repeat and msg in _REPEAT_MESSAGE_CACHE: + return + _REPEAT_MESSAGE_CACHE.add(msg) if log_fmt is not None: msg = log_fmt.format(msg) logger.warning(msg) diff --git a/core/dbt/include/global_project/macros/etc/get_custom_schema.sql b/core/dbt/include/global_project/macros/etc/get_custom_schema.sql index f48fd8113d4..9cc6c72bb4e 100644 --- a/core/dbt/include/global_project/macros/etc/get_custom_schema.sql +++ b/core/dbt/include/global_project/macros/etc/get_custom_schema.sql @@ -3,7 +3,7 @@ Renders a schema name given a custom schema name. If the custom schema name is none, then the resulting schema is just the "schema" value in the specified target. If a schema override is specified, then - the resulting schema is the default schema concatenated with the + the resulting schema is the default schema concatenated with the custom schema. This macro can be overriden in projects to define different semantics @@ -11,9 +11,10 @@ Arguments: custom_schema_name: The custom schema name specified for a model, or none + node: The node the schema is being generated for #} -{% macro generate_schema_name(custom_schema_name=none) -%} +{% macro generate_schema_name(custom_schema_name, node) -%} {%- set default_schema = target.schema -%} {%- if custom_schema_name is none -%} @@ -36,9 +37,10 @@ Arguments: custom_schema_name: The custom schema name specified for a model, or none + node: The node the schema is being generated for #} -{% macro generate_schema_name_for_env(custom_schema_name=none) -%} +{% macro generate_schema_name_for_env(custom_schema_name, node) -%} {%- set default_schema = target.schema -%} {%- if target.name == 'prod' and custom_schema_name is not none -%} diff --git a/core/dbt/parser/base.py b/core/dbt/parser/base.py index e823d2a4c6e..39cb9d0887d 100644 --- a/core/dbt/parser/base.py +++ b/core/dbt/parser/base.py @@ -82,8 +82,9 @@ def get_schema_func(self): 'generate_schema_name', GLOBAL_PROJECT_NAME ) + # this is only true in tests! if get_schema_macro is None: - def get_schema(_): + def get_schema(custom_schema_name=None, node=None): return self.default_schema else: root_context = dbt.context.parser.generate_macro( @@ -117,8 +118,10 @@ def get_alias_func(self): 'generate_alias_name', GLOBAL_PROJECT_NAME ) + + # the generate_alias_name macro might not exist if get_alias_macro is None: - def get_alias(custom_alias_name=None, node=None): + def get_alias(custom_alias_name, node): if custom_alias_name is None: return node.name else: @@ -206,7 +209,21 @@ def _update_parsed_node_info(self, parsed_node, config): # definition, not the current package schema_override = config.config.get('schema') get_schema = self.get_schema_func() - parsed_node.schema = get_schema(schema_override).strip() + try: + schema = get_schema(schema_override, parsed_node) + except dbt.exceptions.CompilationException as exc: + too_many_args = ( + "macro 'dbt_macro__generate_schema_name' takes not more than " + "1 argument(s)" + ) + if too_many_args not in str(exc): + raise + msg = ('The generate_schema_name macro does not accept a second ' + 'argument. This form is deprecated as of 0.14.0') + dbt.exceptions.warn_or_error(msg, node=parsed_node, repeat=False, + log_fmt='WARNING: {}') + schema = get_schema(schema_override) + parsed_node.schema = schema.strip() alias_override = config.config.get('alias') get_alias = self.get_alias_func() diff --git a/test/integration/006_simple_dependency_test/schema_override_legacy_macros/schema.sql b/test/integration/006_simple_dependency_test/schema_override_legacy_macros/schema.sql new file mode 100644 index 00000000000..b2456437d31 --- /dev/null +++ b/test/integration/006_simple_dependency_test/schema_override_legacy_macros/schema.sql @@ -0,0 +1,6 @@ + +{% macro generate_schema_name(schema_name) -%} + + {{ schema_name }}_{{ target.schema }}_macro + +{%- endmacro %} diff --git a/test/integration/006_simple_dependency_test/schema_override_macros/schema.sql b/test/integration/006_simple_dependency_test/schema_override_macros/schema.sql index b2456437d31..615c3fd3b1a 100644 --- a/test/integration/006_simple_dependency_test/schema_override_macros/schema.sql +++ b/test/integration/006_simple_dependency_test/schema_override_macros/schema.sql @@ -1,6 +1,6 @@ -{% macro generate_schema_name(schema_name) -%} +{% macro generate_schema_name(schema_name, node) -%} - {{ schema_name }}_{{ target.schema }}_macro + {{ schema_name }}_{{ node.schema }}_macro {%- endmacro %} diff --git a/test/integration/006_simple_dependency_test/test_local_dependency.py b/test/integration/006_simple_dependency_test/test_local_dependency.py index 27b7a9719a5..6c2a5ca20bd 100644 --- a/test/integration/006_simple_dependency_test/test_local_dependency.py +++ b/test/integration/006_simple_dependency_test/test_local_dependency.py @@ -7,8 +7,7 @@ import dbt.exceptions -class TestSimpleDependency(DBTIntegrationTest): - +class BaseDependencyTest(DBTIntegrationTest): @property def schema(self): return "local_dependency_006" @@ -17,6 +16,12 @@ def schema(self): def models(self): return "test/integration/006_simple_dependency_test/local_models" + def base_schema(self): + return self.unique_schema() + + def configured_schema(self): + return self.unique_schema() + '_configured' + @property def packages_config(self): return { @@ -27,6 +32,17 @@ def packages_config(self): ] } + +class TestSimpleDependency(BaseDependencyTest): + + @property + def schema(self): + return "local_dependency_006" + + @property + def models(self): + return "test/integration/006_simple_dependency_test/local_models" + def base_schema(self): return self.unique_schema() @@ -100,6 +116,34 @@ def test_postgres_local_dependency_out_of_date_no_check(self, mock_get): self.assertEqual(len(results), 3) +class TestDependencyWithLegacySchema(BaseDependencyTest): + @property + def project_config(self): + return { + 'macro-paths': ['test/integration/006_simple_dependency_test/schema_override_legacy_macros'], + 'models': { + 'schema': 'dbt_test', + } + } + + def base_schema(self): + return 'dbt_test_{}_macro'.format(self.unique_schema()) + + def configured_schema(self): + return 'configured_{}_macro'.format(self.unique_schema()) + + @use_profile('postgres') + @mock.patch('dbt.config.project.get_installed_version') + def test_postgres_local_dependency_out_of_date_no_check_no_strict(self, mock_get): + mock_get.return_value = dbt.semver.VersionSpecifier.from_version_string('0.0.1') + self.run_dbt(['deps']) + results = self.run_dbt(['run', '--no-version-check'], strict=False) + self.assertEqual(len(results), 3) + + with self.assertRaises(dbt.exceptions.CompilationException): + results = self.run_dbt(['run', '--no-version-check']) + + class TestSimpleDependencyHooks(DBTIntegrationTest): @property def schema(self): diff --git a/test/integration/043_custom_aliases_test/macros/macros.sql b/test/integration/043_custom_aliases_test/macros/macros.sql index 4bc6a3990e0..17fa7f1ca5e 100644 --- a/test/integration/043_custom_aliases_test/macros/macros.sql +++ b/test/integration/043_custom_aliases_test/macros/macros.sql @@ -1,5 +1,5 @@ -{% macro generate_alias_name(node, custom_alias_name=none) -%} +{% macro generate_alias_name(custom_alias_name, node) -%} {%- if custom_alias_name is none -%} {{ node.name }} {%- else -%}