Skip to main content

Profiler Module: Execution & Extension

This page covers the execution internals and extension points. For the architecture overview and metrics system, see Profiler Module | Architecture & Metrics System.

Profiler Execution Call Chain

Threading Model

The profiler uses a thread pool to parallelize metric computation across columns:
Each thread gets its own QueryRunner instance (_create_thread_safe_runner()) with a dedicated database session. Thread count scales dynamically based on the number of tasks (min 5, max 20).

Metric Filtering

Not all metrics apply to all columns. MetricFilter (processor/metric_filter.py) selects metrics based on:
  1. Column data type — numeric metrics skip string columns (uses orm/registry.py classifiers like is_quantifiable(), is_concatenable())
  2. Global profiler config — admin can enable/disable specific metrics
  3. Table-level config — per-table metric overrides
  4. Database service type — some metrics only work on specific databases

ORM Layer

The orm/ directory bridges SQLAlchemy types with OpenMetadata’s type system:
  • registry.pyPythonDialects maps service types to SQLAlchemy dialects; CustomTypes handles special types (UUID, BYTES, ARRAY)
  • converter/ — database-specific converters (BigQuery, Snowflake, etc.) that map SQLAlchemy column types to OpenMetadata column types
  • functions/ — custom SQL functions used by metrics (e.g., SumFn, LenFn) that handle dialect differences

Database Backend Pluggability

Each database can override the default profiler behavior:
System metrics are also dialect-specific:

Profiler Configuration

The profiler is configured via ProfilerProcessorConfig (api/models.py):

Adding a New Metric

1

Choose the metric type

Decide which base class fits your metric:
2

Implement the metric class

Create a file in the appropriate metrics/ subdirectory.For a StaticMetric, implement fn() returning a SQLAlchemy expression:
For a ComposedMetric, implement fn() using prior results:
3

Register in the Metrics enum

Add your metric to the Metrics enum in metrics/registry.py:
4

Add type filtering (if needed)

If your metric only applies to certain column types, update MetricFilter in processor/metric_filter.py to filter appropriately.

Pandas / DataFrame Support

For non-SQL sources (datalakes, files), the profiler uses a Pandas-based interface with an accumulator pattern (metrics/pandas_metric_protocol.py):
This three-step pattern enables streaming computation over large datasets that don’t fit in memory — each DataFrame chunk updates the accumulator, and the final result is computed after all chunks are processed.

Key Design Patterns

Key Files Quick Reference

All paths above are relative to ingestion/src/metadata/. For example, profiler/processor/core.py means ingestion/src/metadata/profiler/processor/core.py.