Compare commits

...

2 Commits

Author SHA1 Message Date
Drew Banin
ce8b66e9e8 flake8 & mypy 2021-02-04 21:35:49 -05:00
Drew Banin
5536d48610 (#1269) Allow duplicated model names across packages 2021-02-04 21:25:18 -05:00
3 changed files with 49 additions and 5 deletions

View File

@@ -381,6 +381,14 @@ class NameSearcher(Generic[N]):
return model
return None
def search_many(self, haystack: Iterable[N]) -> List[N]:
"""Find multiple entries in the given iterable by name."""
found = []
for model in haystack:
if self._matches(model):
found.append(model)
return found
D = TypeVar('D')
@@ -515,6 +523,16 @@ class Manifest:
}
}
def find_nodes_by_name(
self, name: str, package: Optional[str] = None
) -> List[ManifestNode]:
searcher: NameSearcher = NameSearcher(
name, package, NodeType.refable()
)
result = searcher.search_many(self.nodes.values())
return result
def find_disabled_by_name(
self, name: str, package: Optional[str] = None
) -> Optional[ManifestNode]:

View File

@@ -761,6 +761,21 @@ def raise_duplicate_macro_name(node_1, node_2, namespace) -> NoReturn:
)
def raise_ambiguous_ref(node_1, node_2):
duped_name = node_1.name
get_func = f'{{{{ ref("{duped_name}") }}}}'
raise_compiler_error(
f'The reference {get_func} is ambiguous because there are two nodes '
f'with the name "{duped_name}". To fix this, either change the name '
'of one of these nodes, or use the two-argument version of ref() '
'to specify the package that contains the intended node. Found:\n'
f'- {node_1.unique_id} ({node_1.original_file_path})\n'
f'- {node_2.unique_id} ({node_2.original_file_path})\n\n'
f'Example: {{{{ ref("{node_1.package_name}", "{node_1.name}") }}}}'
)
def raise_duplicate_resource_name(node_1, node_2):
duped_name = node_1.name

View File

@@ -522,11 +522,22 @@ def _check_resource_uniqueness(
relation = relation_cls.create_from(config=config, node=node)
full_node_name = str(relation)
existing_node = names_resources.get(name)
if existing_node is not None:
dbt.exceptions.raise_duplicate_resource_name(
existing_node, node
)
# Check refs - is there an unqualified ref to a
# model that exists in two different packages?
for ref in node.refs:
if len(ref) == 1:
matched = manifest.find_nodes_by_name(ref[0])
else:
# two-arg refs are namespaced, so no need
# to check for duplicates. Nodes must still
# have unique names within a package
continue
if len(matched) > 1:
dbt.exceptions.raise_ambiguous_ref(
matched[0],
matched[1]
)
existing_alias = alias_resources.get(full_node_name)
if existing_alias is not None: