Skip to content

Row Tracing

Trace the complete journey of any row through your pipeline.

Basic Usage

# By row index
trace = tp.trace(df, row=0)
print(trace)

# By business key
trace = tp.trace(df, where={"customer_id": "C-12345"})
print(trace)

Output:

Row 42 Journey:
  Status: [OK] Alive

  Events: 3
    [SURVIVED] DataFrame.dropna
    [MODIFIED] DataFrame.fillna: income
    [SURVIVED] DataFrame.__getitem__[mask]

The TraceResult Object

trace = tp.trace(df, row=0)

# Access fields
trace.row_id           # int: internal row ID
trace.status           # str: "alive" or "dropped"
trace.events           # list[TraceEvent]: all events

# For dropped rows
trace.dropped_by       # str: operation that dropped the row
trace.dropped_at_step  # int: step number

# Export
trace.to_dict()        # dict representation

Finding Rows

By Index

# Current DataFrame index
tp.trace(df, row=0)      # First row in current df
tp.trace(df, row=-1)     # Last row in current df

By Business Key

# Single key
tp.trace(df, where={"email": "alice@example.com"})

# Multiple keys (AND condition)
tp.trace(df, where={"region": "US", "status": "active"})

# Find row with null value
tp.trace(df, where={"email": None})

Use Business Keys

Business keys are more stable than row indices, which change as rows are filtered.

Event Types

Event Type Description
SURVIVED Row passed through operation unchanged
MODIFIED One or more cells changed
DROPPED Row was removed
CREATED Row first appeared (e.g., from merge)

Tracing Dropped Rows

You can trace rows that were dropped:

dbg = tp.debug.inspect()

# Get IDs of dropped rows
dropped_ids = dbg.dropped_rows()

# Trace a specific dropped row
for rid in list(dropped_ids)[:5]:
    trace = dbg.explain_row(rid)
    print(f"Row {rid}: dropped by {trace.dropped_by}")

Merge Parent Tracking

For rows created by merges, TracePipe tracks their parents:

result = df1.merge(df2, on="id")
trace = tp.trace(result, row=0)

# In debug mode, you can see parent rows
if trace.merge_parents:
    print(f"Left parent: {trace.merge_parents.left}")
    print(f"Right parent: {trace.merge_parents.right}")

Performance Considerations

  • Row tracing in CI mode is limited (no individual row IDs)
  • For large DataFrames, use where= with indexed columns for faster lookups
  • Tracing many rows? Use tp.debug.inspect() for batch access