Visualization Utilities#
Module name: postbound.vis
Note that this module requires a number of additional dependencies. They can be installed via the vis extra:
pip install postbound[vis]
Contains utilities to visualize different PostBOUND objects.
- postbound.vis.annotate_cards(table: TableReference, *, query: SqlQuery, database: Database | None = None) str#
Annotates the nodes of a join graph with true cardinalities before and after filters.
Cardinalities are calculated by issuing actual count(*) queries to the database. Two values are reported: the total cardinality of the table (before filters) and the cardinality after applying all applicable filter predicates from the query.
- Parameters:
table (TableReference) – The table to estimate
query (SqlQuery) – The SQL query being optimized. This is required to infer all filter predicates
database (Optional[Database], optional) – The database to calculate the cardinalities on. If None, the current database from the DatabasePool is used.
- Return type:
str
See also
- postbound.vis.annotate_estimates(node: QueryPlan) str#
Annotates the nodes of a query plan with estimated cost and cardinality.
See also
- Parameters:
node (QueryPlan)
- Return type:
str
- postbound.vis.annotate_filter_cards(table: TableReference, *, query: SqlQuery, database: Database | None = None) str#
Annotates the nodes of a join graph with true cardinalities after filters.
Cardinalities are calculated by issuing actual count(*) queries to the database. All applicable filter predicates are included in the query.
- Parameters:
table (TableReference) – The table to estimate
query (SqlQuery) – The SQL query being optimized. This is required to infer all filter predicates
database (Optional[Database], optional) – The database to calculate the cardinalities on. If None, the current database from the DatabasePool is used.
- Return type:
str
See also
- postbound.vis.estimated_cards(table: TableReference, *, query: SqlQuery, database: Database | None = None) str#
Annotates the nodes of a join graph with estimated cardinalities.
Estimated cardinalities are obtained by asking the actual query optimizer from the database. Usually, they are calculated after all matching filter predicates have been applied.
- Parameters:
table (TableReference) – The table to estimate
query (SqlQuery) – The SQL query being optimized. This is required to infer all filter predicates
database (Optional[Database], optional) – The database whose optimizer is used to estimate the cardinalities. If None, the current database from the DatabasePool is used.
- Return type:
str
See also
- postbound.vis.force_directed_layout(elements: Iterable[T], difference_score: Callable[[T, T], float]) dict[T, ndarray]#
Lays out the supplied elements in a 2D-space according to the difference score.
Pairs of points with a large difference score are positioned further apart than points with a low difference score.
The returned dictionary maps each of the input element to the pair of (x, y) coordinates.
- Parameters:
elements (Iterable[T])
difference_score (Callable[[T, T], float])
- Return type:
dict[T, ndarray]
- postbound.vis.plot_analyze_plan(plan: QueryPlan, *, skip_intermediates: bool = False, **kwargs) Graph#
Creates a Graphviz visualization of an EXPLAIN ANALYZE query plan.
This is a convenience wrapper around plot_query_plan that uses a default annotation generator suitable for showing runtime information contained in EXPLAIN ANALYZE plans.
- Parameters:
plan (QueryPlan)
skip_intermediates (bool)
- Return type:
Graph
- postbound.vis.plot_join_graph(query_or_join_graph: SqlQuery | JoinGraph, table_annotations: Callable[[TableReference], str] | None = None, *, include_pk_fk_joins: bool = False, out_path: str = '', out_format: str = 'svg') Graph | Digraph#
Creates a Graphviz visualization of a join graph.
The join graph can be either supplied directly (in which case it will be visualized as a directed graph), or implicitly through its SQL query. In this case, the join graph is inferred based on the join conditions. Such a graph can be further customized to also highlight primary-key/foreign-key relationships as a directed graph.
The directed graph variants will point from the foreign key table to the primary key table.
To customize the information shown on each table node, a custom table_annotations function can be provided. Several such functions for common annotations are already provided in this module. Annotation functions have a very simple signature: they take the table currently being rendered as input and return a string containing the metadata to be shown on the node. To add additional context to these methods, it is advisable to use functools.partial to bind additional parameters.
See also
estimated_cards,annotate_filter_cards,annotate_cards,merged_annotation- Parameters:
table_annotations (Callable[[TableReference], str] | None)
include_pk_fk_joins (bool)
out_path (str)
out_format (str)
- Return type:
Graph | Digraph
- postbound.vis.plot_join_tree(join_tree: JoinTree) Graph#
Creates a Graphviz visualization of a join tree.
- Parameters:
join_tree (JoinTree)
- Return type:
Graph
- postbound.vis.plot_query_plan(plan: QueryPlan, annotation_generator: Callable[[QueryPlan], str] | None = None, *, skip_intermediates: bool = False, **kwargs) Graph#
Creates a Graphviz visualization of a query plan.
By default, each node is just annotated with its operator type and base table (for scans). To add additional information (e.g., estimated or true cardinality), a custom annotation_generator function can be provided. Such a function takes the current QueryPlan node as input and returns a string containing the metadata to be shown on the node. Since this signature is quite simple, it is advisable to use functools.partial to bind additional parameters to the function. This module already provides the most common annotation function: annotate_estimates, which adds estimated cost and cardinality.
For EXPLAIN ANALYZE plans (i.e. plans containing runtime information), the plot_analyze_plan function has as meaningful default annotation generator.
See also
- postbound.vis.plot_relalg(relnode: RelNode, **kwargs) Graph#
Creates a Graphviz visualization of a relational algebra expression tree.
Additional keyword arguments are passed to plot_tree.
- Parameters:
relnode (RelNode)
- Return type:
Graph
- postbound.vis.plot_tree(node: ~postbound._base.T, label_generator: ~collections.abc.Callable[[~postbound._base.T], tuple[str, dict]], child_supplier: ~collections.abc.Callable[[~postbound._base.T], ~collections.abc.Sequence[~postbound._base.T]], *, escape_labels: bool = True, out_path: str = '', out_format: str = 'svg', node_id_generator: ~collections.abc.Callable[[~postbound._base.T], int] = <built-in function hash>, _graph: ~graphviz.graphs.Graph | None = None, **kwargs) Graph#
Transforms an arbitrary tree into a Graphviz graph. The tree traversal is achieved via callback functions.
Start the traversal at the root node.
- Parameters:
node (T) – The node to plot.
label_generator (Callable[[T], tuple[str, dict]]) – Callback function to generate labels of the nodes in the graph. The dictionary can contain additional formatting attributes (e.g. bold font). Consult the Graphviz documentation for allowed values
child_supplier (Callable[[T], Sequence[T]]) – Provides the children of the current node.
escape_labels (bool, optional) – Whether to escape the labels of the nodes. Defaults to True. If set to False, the labels will be rendered as-is and all HTML-like tags will be interpreted as such.
out_path (str, optional) – An optional file path to store the graph at. If empty, the graph will only be provided as a Graphviz object.
out_format (str, optional) – The output format of the graph. Defaults to SVG and will only be used if the graph should be stored to disk (according to out_path).
node_id_generator (Callable[[T], int], optional) – Callback function to generate unique identifiers for the nodes. Defaults to the hash function of the nodes. These identifiers are only used internally to identify the different nodes in the graph.
_graph (Optional[gv.Graph], optional) – Internal parameter used for state-management within the plotting function. Do not set this parameter yourself!
- Returns:
_description_
- Return type:
gv.Graph
See also
gv.Dot.node,gv.Dot.edgeReferences
- postbound.vis.setup_annotations(*annotations: Literal['estimated-cards', 'filter-cards', 'true-cards'], query: SqlQuery, database: Database | None = None) Callable[[TableReference], str]#
Annotates the nodes of a join graph with different cardinality estimates.
- Parameters:
- Return type:
Callable[[TableReference], str]