Dag-level checks
SQL check operators that run as part of your pipeline, with full control over failure behavior and notifications.
Pre-load checks
The
AnalyticsOperator runs SQL against files in object storage before they are loaded.Third-party frameworks
Great Expectations, dbt tests, and Soda Core for additional validation capabilities.
This guide uses Airflow 3.3 and version 2.1 of the Common SQL provider. If you use a different version, especially a different major version, some details might not apply to your setup.
Types of data quality challenges
- Volume anomalies: Unexpected spikes or drops in row counts.
- Schema drift: Column types changing without notice.
- Completeness issues: Null values in critical fields.
- Duplicate records: Compromising uniqueness constraints.
- Business rule violations: Negative amounts, invalid dates, orphaned records.
Where to run your checks
Data quality checks can be run at multiple points in a pipeline. Often teams want two different checks: against files before they are loaded, and against tables after the load.Dag-level checks do not have to stop your pipelineYou have several options to control failure behavior:
- Trigger rules: Use trigger rules like
all_doneornone_failed_min_one_successon downstream tasks to continue despite failed checks. See Airflow trigger rules. - Branching: Use the
BranchSQLOperatorto route to a quarantine path instead of failing. - Shell exit code handling: When calling third-party frameworks through
@task.bash, append|| trueor|| exit 0to prevent non-zero exit codes from failing the task. - Skip instead of fail: Set
skip_on_exit_codein@task.bash(...)to mark tasks as skipped rather than failed.
on_failure_callback still fires, ensuring you can get notified about check failures without blocking your pipeline.Choose a tool
Which tool you choose is determined by the needs and preferences of your organization. Astronomer recommends using Dag-level checks with SQL check operators if you want to:- Write checks without needing to set up software in addition to Airflow.
- Write checks as Python dictionaries and in SQL.
- Use any SQL statement that returns a single row of booleans as a data quality check.
- Implement many different downstream dependencies depending on the outcome of different checks.
- Have full observability of which checks failed from within Airflow task logs, including the full SQL statements of failed checks.
- You want to collect the results of your data quality checks in a central place.
- You prefer to write checks in JSON (Great Expectations) or YAML (Soda).
- Most or all of your checks can be implemented by the predefined checks in the solution of your choice.
- You want to abstract your data quality checks from the Dag code.
AnalyticsOperator to validate incoming files before they are loaded.
Dag-level checks with Airflow
When to use each operator
SQL check operators
To access the SQL check operators, install the Common SQL provider:SQLCheckOperator
SQLCheckOperator
The
SQLCheckOperator is the most generic check operator. It runs any SQL query and evaluates the result, giving you enough freedom to cover complex business rules. The check fails if any returned value evaluates to False in Python (for example, 0, None, empty string).SQLColumnCheckOperator
SQLColumnCheckOperator
The
SQLColumnCheckOperator validates individual columns using built-in check types. Define a column_mapping dictionary to run multiple checks in a single task.Built-in check types:Comparison options:
equal_to,greater_than,geq_to(>=)less_than,leq_to(<=)tolerance(percentage threshold, as a fraction:0.1= 10%)
partition_clauseThe optional
partition_clause is an additional WHERE filter applied before the checks. It can be added at the operator level (partitions all checks), at the column level in the column mapping (partitions all checks for that column), or at the check level (partitions just that check).SQLTableCheckOperator
SQLTableCheckOperator
The The
SQLTableCheckOperator runs custom SQL expressions against a given table that must evaluate to true. It is suited for business rules spanning multiple columns or requiring aggregations.SQLTableCheckOperator also supports an optional partition_clause on check level for an additional WHERE filter applied before the check.SQLValueCheckOperator
SQLValueCheckOperator
Performs a simple value check by comparing a SQL result to an expected value (
pass_value). The value can be of any type. For numerical values, you can set an additional tolerance percentage.SQLIntervalCheckOperator
SQLIntervalCheckOperator
Verify that metrics defined as SQL expressions remain within tolerance compared to those from previous days (
days_back). This utility helps track how values change over time and identify potential outliers.DefaultsThe default for
days_back is -7, and ds for the date_filter_column. Always set date_filter_column explicitly to your table’s actual date column.SQLThresholdCheckOperator
SQLThresholdCheckOperator
Performs a value check against a minimum and maximum threshold.
SQL expression thresholdsThresholds can also be SQL expressions, not just numeric values. For example:
min_threshold="SELECT MIN(target_avg) FROM benchmarks".Notifications
Detecting data quality issues is only part of the story. The other part is raising awareness. To be notified when a data quality check fails, combine theon_failure_callback task parameter with Airflow notifiers.
Slack example:
To use the SlackNotifier, install the following package:
task.table and the actual quality issue through exception.
SlackNotifierThe
SlackNotifier requires a properly configured Slack connection. In this case, the connection ID is slack_default.AppriseNotifierThe
AppriseNotifier supports 100+ notification services (Slack, Email, PagerDuty, Teams, etc.) through a unified interface. Install it using apache-airflow-providers-apprise.Check patterns
Astronomer recommends running column checks first (field-level validation), followed by table checks (business logic), and then proceed with downstream processing. Additionally, use task groups to organize your data quality checks and use thedefault_args parameter to configure notifications for all checks at once.
Pre-load checks with the AnalyticsOperator
TheAnalyticsOperator runs SQL directly against files in object storage using Apache DataFusion. Use it to validate files before they are loaded into a warehouse.
The operator reads from Amazon S3 and the local filesystem, supports the Parquet, CSV, and Avro formats, and queries Apache Iceberg tables through a catalog.
To access the AnalyticsOperator, install the Common SQL provider with the datafusion extra:
Define a datasource
ADataSourceConfig defines the location and format of the files the operator queries:
table_name is the identifier you reference in your queries. It does not have to exist in a database.
Partitioned dataFor partitioned data, pass the partition columns through
options. For example: options={"table_partition_cols": [("year", "integer")]}.Run the checks
Pass your datasource configs and a list of queries to the operator:Fail the task on the results
TheAnalyticsOperator runs your queries and returns the results. Unlike the SQL check operators, it does not evaluate a condition or fail. If you want to fail your Dag based on the check results, add a downstream task that reads the results and raises an exception:
Aggregate in SQL
max_rows_check defaults to 100. Aggregate in SQL rather than pulling rows into XCom. A check should return a number, not a dataset.Third-party frameworks
Great Expectations
The airflow-provider-great-expectations package provides operators for running Great Expectations validations directly in your Dags. When deciding which operator fits your use case, consider:- Where is your data? In memory as a DataFrame, or in an external data source?
- Do you need to trigger actions? Such as sending notifications or updating external systems based on validation results.
- What Data Context do you need? Ephemeral for stateless validations, or persistent to track results over time.
See Orchestrate Great Expectations with Airflow to learn how to use these operators in your Dag.
dbt tests
If you use dbt with Airflow through Cosmos, use dbt’s built-in testing framework:- Schema tests:
unique,not_null,accepted_values,relationships. - Custom tests: SQL-based assertions for business-specific validation.
Soda Core
Run Soda checks using@task.bash:
Quick reference
Conclusion
Pre-load checks with theAnalyticsOperator validate files before they are loaded, without warehouse compute. Dag-level SQL check operators validate tables after the load and fail the task when a check does not pass.
Many teams should use both, and set the failure behavior for each check based on whether it should stop the pipeline.