Skip to main content

Metadata Ingestion

The metadata ingestion framework lives at ingestion/src/metadata/ingestion/. It extracts metadata (databases, schemas, tables, columns, dashboards, pipelines, etc.) from external systems and publishes it to the OpenMetadata server. This guide covers the core framework architecture. For usage and lineage ingestion — which build on these same patterns — see the dedicated pages.

Core Pipeline

Every ingestion workflow follows the Source → Sink pattern, orchestrated by workflow/metadata.py:

Topology-Based Execution

The key architectural pattern is the topology. Instead of hand-coded loops, each source declares a tree of TopologyNode objects that the framework traverses depth-first.

How It Works

A topology is a tree where each node has:
  • producer — a method that yields raw items (e.g., database names)
  • stages — processing steps that transform each item into an entity request
  • children — child nodes to recurse into
  • post_process — cleanup methods run after all children complete

Database Service Topology

This is the topology for all SQL database connectors (source/database/database_service.py):

Execution Engine

TopologyRunnerMixin (api/topology_runner.py) drives the traversal:
Nodes marked with threads=True distribute items across a thread pool. Each thread gets a copy of the TopologyContext.

Topology Context

TopologyContext is a thread-safe state object that tracks the current position in the hierarchy. As the traversal descends, it stores the current service, database, schema, etc., so child nodes can build fully qualified names (FQNs):

Source Class Hierarchy

For database connectors, the class hierarchy is:

Key Methods in CommonDbSourceService

Column Type Parsing

ColumnTypeParser (source/database/column_type_parser.py) maps database-specific types to OpenMetadata’s DataType enum:
  • Handles complex types: JSON, ARRAY, STRUCT, MAP
  • Extracts precision/scale for numeric types
  • Supports database-specific type aliases

Constraint Handling

SqlColumnHandlerMixin (source/database/sql_column_handler.py) processes:
  • Primary keys — from inspector.get_pk_constraint()
  • Unique constraints — from inspector.get_unique_constraints()
  • Foreign keys — from inspector.get_foreign_keys(), including cross-database references

Other Service Topologies

The same topology pattern applies to all service types:

Dashboard Service

Pipeline Service

Messaging Service

Storage, Search, ML Model, API Services

Each follows the same pattern with service-specific entity types.

MetadataRestSink

The sink (sink/metadata_rest.py) uses @singledispatchmethod to route entity types:

Fingerprinting

Every entity carries a sourceHash computed from its metadata. The sink uses this to decide:
  • CREATE — entity doesn’t exist yet
  • PATCH — entity exists but hash differs (metadata changed)
  • SKIP — entity exists and hash matches (no changes)
This enables incremental ingestion — only changed entities are written.

Filtering

Filters are applied at the producer level (before any processing):
Available filter patterns:
  • databaseFilterPattern — include/exclude databases by regex
  • schemaFilterPattern — include/exclude schemas
  • tableFilterPattern — include/exclude tables
  • Plus service-specific filters (topic, pipeline, dashboard, etc.)

Connection Management

source/connections.py dynamically loads and creates database connections:
  • Each service type has a connection class (e.g., PostgresConnection, SnowflakeConnection)
  • get_connection() resolves the class and returns a SQLAlchemy Engine or API client
  • test_connection() validates connectivity before processing

Multi-Threading

Nodes can enable multi-threaded processing for parallelism:
The TopologyContextManager ensures each thread gets an isolated copy of the context while sharing the database connection.

OpenMetadata API Client

The OpenMetadata class (ometa/ometa_api.py) is composed of 25+ mixins: The underlying REST client (ometa/client.py) handles authentication, retries, and response parsing.

Key Design Patterns

Key Files Quick Reference

All paths above are relative to ingestion/src/metadata/ingestion/. For example, api/steps.py means ingestion/src/metadata/ingestion/api/steps.py.