Files
fn_registry/python/functions/datascience/build_join_graph.md
T
egutierrez 763e06c127 feat(browser): auto-commit con 178 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-20 18:22:23 +02:00

5.3 KiB

id, name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, example, tested, tests, test_file_path, file_path, params, output
id name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports example tested tests test_file_path file_path params output
build_join_graph_py_datascience build_join_graph function py datascience 1.0.0 pure def build_join_graph(fk_candidates: list, tables: list = None) -> dict Construye un grafo de relaciones inter-tabla a partir de FK candidatas (salida fk_candidates de infer_fk_containment_duckdb): nodos con grados y rol (fact/dimension/bridge/standalone), aristas por FK, hubs (candidatas a tabla de hechos) y un diagrama Mermaid graph LR pegable. Funcion pura, sin deps externas, no muta el input.
eda
relations
join
schema
graph
mermaid
star-schema
datascience
false
from datascience import build_join_graph fks = [ {"from_table": "orders", "from_col": "customer_id", "to_table": "customers", "to_col": "id", "inclusion": 1.0, "cardinality": "many-to-one"}, {"from_table": "orders", "from_col": "product_id", "to_table": "products", "to_col": "id", "inclusion": 0.98, "cardinality": "many-to-one"}, ] g = build_join_graph(fks) # g["hubs"] == ["orders"]; orders -> role "fact", customers/products -> "dimension" print(g["mermaid"]) true
test_star_schema_roles_and_hub
test_two_edges_built
test_mermaid_contains_tables_and_arrows
test_bridge_role
test_standalone_node_from_tables_list
test_empty_list_does_not_crash
test_none_input_does_not_crash
test_malformed_entries_skipped
test_does_not_mutate_input
python/functions/datascience/build_join_graph_test.py python/functions/datascience/build_join_graph.py
name desc
fk_candidates lista de dicts, cada uno una FK candidata con al menos las claves from_table, from_col, to_table, to_col, inclusion, cardinality. Suele ser la salida `fk_candidates` de infer_fk_containment_duckdb. Las claves se leen de forma defensiva con .get(...); entradas que no son dict o que no tienen from_table/to_table se ignoran sin fallar. None se trata como [].
name desc
tables lista opcional de nombres de TODAS las tablas. Sirve para incluir como nodos aislados (role "standalone") las tablas que no aparecen en ninguna FK. Si es None, los nodos se derivan solo de las aristas.
dict con nodes (list[dict] con table, out_degree, in_degree, role donde role es "fact"|"dimension"|"bridge"|"standalone"), edges (list[dict] con from_table, from_col, to_table, to_col, inclusion, cardinality, una por FK valida), mermaid (str con un diagrama `graph LR` pegable en un bloque ```mermaid, una arista por FK etiquetada `from_col->to_col`) y hubs (list[str] de tablas con out_degree>0 ordenadas por out_degree descendente, candidatas a tabla de hechos / star schema).

Ejemplo

from datascience import build_join_graph

# fk_candidates concreto: orders apunta a customers y a products (estrella).
fks = [
    {"from_table": "orders", "from_col": "customer_id",
     "to_table": "customers", "to_col": "id",
     "inclusion": 1.0, "cardinality": "many-to-one"},
    {"from_table": "orders", "from_col": "product_id",
     "to_table": "products", "to_col": "id",
     "inclusion": 0.98, "cardinality": "many-to-one"},
]

g = build_join_graph(fks)

g["hubs"]   # ["orders"]
# nodes: orders -> role "fact" (out_degree 2, in_degree 0),
#        customers/products -> role "dimension" (in_degree 1, out_degree 0)
print(g["mermaid"])

El campo mermaid se pega tal cual en un bloque ```mermaid:

graph LR
    orders["orders"] -->|customer_id->id| customers["customers"]
    orders["orders"] -->|product_id->id| products["products"]

Cuando usarla

Cuando hayas inferido las foreign keys de una base de datos con infer_fk_containment_duckdb (grupo eda) y necesites visualizar el esquema relacional: ver de un vistazo que tabla es la de hechos (hub/star schema), cuales son dimensiones y cuales quedan sueltas. Devuelve un diagrama Mermaid pegable en docs, un report o un dashboard, mas el grafo en dict para razonar sobre los grados (priorizar joins, detectar tablas puente, planear el modelo dimensional). Es la capa de grafo sobre las FK crudas: lee las candidatas, no toca la base de datos.

Notas

Funcion pura, sin I/O ni dependencias externas (solo stdlib), no muta fk_candidates. Tolera lista vacia o None (devuelve grafo vacio con un mermaid minimo graph LR con nota empty) y entradas malformadas (no-dict o sin from_table/to_table se ignoran).

Heuristica de role por nodo, basada solo en grados:

  • factout_degree > 0 y in_degree == 0: apunta a otras tablas y nadie le apunta. Es la candidata a tabla de hechos.
  • dimensionin_degree > 0 y out_degree == 0: solo recibe referencias (tabla maestra / catalogo).
  • bridgeout_degree > 0 e in_degree > 0: apunta y recibe (tabla puente o asociativa de una relacion many-to-many).
  • standalone — sin aristas (solo aparece si se paso en tables).

hubs ordena por out_degree descendente las tablas con out_degree > 0. Para un star schema limpio, hubs[0] es la tabla de hechos. Los IDs de nodo en el Mermaid se sanean (no-alfanumerico -> _) pero la etiqueta visible conserva el nombre original de la tabla.