diff --git a/graph.py b/graph.py index 7cc68c2..a839984 100644 --- a/graph.py +++ b/graph.py @@ -126,12 +126,14 @@ def _add_related_rows_to_graph(row, row_node, graph): except TypeError: # This path for foreign keys. related_row = related_rows - related_node = Node( - table=_get_table_name_from_row(related_row), - primary_key=_get_primary_key_from_row(related_row), - data=_get_data(related_row), - ) - related.append((related_row, related_node)) + # Ignore null foreign-keys. + if related_row is not None: + related_node = Node( + table=_get_table_name_from_row(related_row), + primary_key=_get_primary_key_from_row(related_row), + data=_get_data(related_row), + ) + related.append((related_row, related_node)) unvisited = [ (row, node) for (row, node) in related if node not in graph.nodes diff --git a/pyproject.toml b/pyproject.toml index 6580c5e..c530e5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "fk-graph" -version = "0.0.4" +version = "0.0.5" authors = [ { name="Andrew Curtis", email="fk.graph@fastmail.com" }, { name="John C Thomas" }, diff --git a/test_graph.py b/test_graph.py index 1b13460..99b6c2d 100644 --- a/test_graph.py +++ b/test_graph.py @@ -151,6 +151,14 @@ def test_can_restrict_to_selected_tables(self): any([n.table == "table_c" for n in graph.nodes]) ) + def test_can_create_graph_when_some_rows_have_null_foreign_keys(self): + self._create_entries_with_null_foreign_key(self.engine) + + graph = get_graph(self.engine, "table_a", "1") + + # Check does not add null nodes to graph. + self.assertEqual(len(graph.nodes), 1) + def _create_single_table_no_relations(self, engine): metadata_object = MetaData() table_a = Table( @@ -312,6 +320,29 @@ def _create_data_with_non_primary_key_non_foreign_kay_fields(self, engine): ) conn.commit() + def _create_entries_with_null_foreign_key(self, engine): + metadata_object = MetaData() + table_a = Table( + "table_a", + metadata_object, + Column("id", Integer, primary_key=True), + Column("b_id", ForeignKey("table_b.id"), nullable=True), + ) + table_b = Table( + "table_b", + metadata_object, + Column("id", Integer, primary_key=True), + ) + metadata_object.create_all(engine) + with engine.connect() as conn: + conn.execute( + insert(table_a), + [ + {"id": 1, "b_id": None}, + ] + ) + conn.commit() + def _to_table_primary_keys(nodes): return [