Querying Provenance
Once provenance is recorded, you can query the database using tisserande’s layered operations.
Synchronous Queries
For scripts and CLI tools, use the local_sync layer:
from tisserande.local_sync import execution, node, edge
# Get all executions
all_executions = execution.get_rows()
# Get a specific execution by ID
ex = execution.get_row(some_uuid)
# Get all nodes for an execution
from macon.models import Filter, FilterOp
exec_nodes = node.filter_rows(
filters=[Filter(field="execution_id", op=FilterOp.EQ, value=str(some_uuid))]
)
# Get all edges for an execution
exec_edges = edge.filter_rows(
filters=[Filter(field="execution_id", op=FilterOp.EQ, value=str(some_uuid))]
)
Async Queries
For async contexts (e.g., inside a FastAPI endpoint), use the local_async layer:
from tisserande.local_async import execution, node, edge
all_executions = await execution.get_rows()
ex = await execution.get_row(some_uuid)
Available Operations
All table operations support the full macon CRUD interface:
Method |
Description |
|---|---|
|
Get a single record by primary key |
|
Get a record by unique name (type tables only) |
|
Get multiple records with pagination |
|
Create a new record |
|
Update an existing record |
|
Delete a record |
|
Filter records with operators (eq, ne, lt, gt, like, etc.) |
|
Count total records |
Available Tables
Each table is accessible as a module-level instance:
Type tables (lookup tables):
data_file_type— types of data filesconfig_file_type— types of config filesconfig_dict_type— types of config dictsparameter— parameter definitionsarray— array definitionsclass_— Python class definitionspython_function— Python function definitionsmember_function— member function definitionsshell_function— shell function definitions
Core provenance tables:
node— all provenance graph nodesedge— all provenance graph edgesexecution— all execution records
Example: Trace a File’s Lineage
Find all executions that produced a given output file:
from tisserande.local_sync import node, edge
from macon.models import Filter, FilterOp
# Find the node for our output file
output_nodes = node.filter_rows(
filters=[
Filter(field="type_", op=FilterOp.EQ, value="data_file"),
Filter(field="path", op=FilterOp.EQ, value="/data/output.fits"),
]
)
# Find edges pointing TO this node (from a function)
for output_node in output_nodes:
incoming_edges = edge.filter_rows(
filters=[Filter(field="to_id", op=FilterOp.EQ, value=str(output_node.id_))]
)
for e in incoming_edges:
# e.from_id is the function node that produced this output
func_node = node.get_row(e.from_id)
print(f"Produced by execution: {func_node.execution_id}")