diff --git a/.changes/unreleased/Fixes-20230526-153738.yaml b/.changes/unreleased/Fixes-20230526-153738.yaml new file mode 100644 index 00000000000..6fe6929898c --- /dev/null +++ b/.changes/unreleased/Fixes-20230526-153738.yaml @@ -0,0 +1,6 @@ +kind: Fixes +body: fix StopIteration error when publication for project not found +time: 2023-05-26T15:37:38.952939-04:00 +custom: + Author: michelleark + Issue: "7711" diff --git a/core/dbt/contracts/publication.py b/core/dbt/contracts/publication.py index d6cfa67b751..ca201503888 100644 --- a/core/dbt/contracts/publication.py +++ b/core/dbt/contracts/publication.py @@ -97,8 +97,6 @@ class PublicationMandatory: @dataclass @schema_version("publication", 1) class PublicationArtifact(ArtifactMixin, PublicationMandatory): - """This represents the _publication.json artifact""" - public_models: Dict[str, PublicModel] = field(default_factory=dict) metadata: PublicationMetadata = field(default_factory=PublicationMetadata) # list of project name strings diff --git a/core/dbt/parser/manifest.py b/core/dbt/parser/manifest.py index 50ce0430a06..07f195bf57e 100644 --- a/core/dbt/parser/manifest.py +++ b/core/dbt/parser/manifest.py @@ -243,7 +243,11 @@ def __init__( self.root_project: RuntimeConfig = root_project self.all_projects: Mapping[str, Project] = all_projects self.file_diff = file_diff - self.publications = publications + self.publications: Mapping[str, PublicationArtifact] = ( + {publication.project_name: publication for publication in publications} + if publications + else {} + ) self.manifest: Manifest = Manifest() self.new_manifest = self.manifest self.manifest.metadata = root_project.get_metadata() @@ -841,20 +845,18 @@ def build_public_nodes(self) -> bool: def load_new_public_nodes(self): for project in self.manifest.project_dependencies.projects: - publication = ( - next(p for p in self.publications if p.project_name == project.name) - if self.publications - else None - ) - if publication: - publication_config = PublicationConfig.from_publication(publication) - self.manifest.publications[project.name] = publication_config - # Add to dictionary of public_nodes and save id in PublicationConfig - for public_node in publication.public_models.values(): - self.manifest.public_nodes[public_node.unique_id] = public_node - else: + try: + publication = self.publications[project.name] + except KeyError: raise PublicationConfigNotFound(project=project.name) + publication_config = PublicationConfig.from_publication(publication) + self.manifest.publications[project.name] = publication_config + + # Add to dictionary of public_nodes and save id in PublicationConfig + for public_node in publication.public_models.values(): + self.manifest.public_nodes[public_node.unique_id] = public_node + def is_partial_parsable(self, manifest: Manifest) -> Tuple[bool, Optional[str]]: """Compare the global hashes of the read-in parse results' values to the known ones, and return if it is ok to re-use the results. diff --git a/tests/functional/multi_project/test_publication.py b/tests/functional/multi_project/test_publication.py index 754d02dc73e..662620f7763 100644 --- a/tests/functional/multi_project/test_publication.py +++ b/tests/functional/multi_project/test_publication.py @@ -133,10 +133,14 @@ def models(self): def test_pub_artifacts(self, project): write_file(dependencies_yml, "dependencies.yml") - # Dependencies lists "marketing" project, but no publication file found + # Dependencies lists "marketing" project, but no publications provided with pytest.raises(PublicationConfigNotFound): run_dbt(["parse"]) + # Dependencies lists "marketing" project, but no "marketing" publication provided + with pytest.raises(PublicationConfigNotFound): + run_dbt(["parse"], publications=[PublicationArtifact(project_name="not_marketing")]) + # Provide publication and try again m_pub_json = marketing_pub_json.replace("test_schema", project.test_schema) publications = [PublicationArtifact.from_dict(json.loads(m_pub_json))]