How to Validate DataFrames With pandera

pandera lets you declare a schema for a pandas DataFrame - column types, nullability, regex patterns, numeric ranges - and validate the whole thing in one call. With lazy=True you get every failing row and rule at once, not just the first one.

Data Engineerpythonpanderadata-quality

What pandera does

pandera is a pandas-native schema validator. You declare a DataFrameSchema that maps each column to its expected type and one or more Check constraints. When you call schema.validate(df), pandera compares every value in the DataFrame against those rules and raises SchemaErrors on the first violation - or, with lazy=True, collects all violations before raising.

This is the difference between a data-quality gate that stops a bad batch versus one that just points at the first bad row and leaves you hunting for more.

Declaring a schema

import pandas as pd
import pandera.pandas as pa

schema = pa.DataFrameSchema(
    {
        "email": pa.Column(
            str,
            nullable=False,
            checks=pa.Check.str_matches(r"^[^@]+@[^@]+\.[^@]+$"),
        ),
        "age": pa.Column(
            int,
            checks=pa.Check.in_range(18, 120),
        ),
        "order_total": pa.Column(
            float,
            checks=pa.Check.ge(0),
        ),
    },
    coerce=True,  # cast CSV strings to the declared dtype
)

coerce=True is important when reading from CSV: pandas reads ambiguous columns as object (string), so without coercion the dtype check on age (declared int) would fail immediately.

Validating lazily and handling failures

import sys

df = pd.read_csv("customers.csv")

try:
    schema.validate(df, lazy=True)
except pa.errors.SchemaErrors as e:
    print("validation failed:")
    for _, row in e.failure_cases.iterrows():
        print(f"  FAIL {row['column']} / {row['check']}: {row['failure_case']}")
    sys.exit(1)

print("all checks passed")
sys.exit(0)

e.failure_cases is a DataFrame with columns column, check, failure_case, and index - so you can log, alert, or write the bad rows to a quarantine table rather than losing context.

Key checks at a glance

Constraint pandera
non-null nullable=False on pa.Column
regex pattern pa.Check.str_matches(r"...")
numeric range pa.Check.in_range(min, max)
greater-or-equal pa.Check.ge(0)
allow-list pa.Check.isin(["a", "b", "c"])

Where this fits in a pipeline

A validate.py script that exits non-zero on failure becomes a hard gate in any ETL: Airflow's BashOperator or PythonOperator marks the task failed; a shell pipeline stops on set -e; a CI check blocks the merge. The bad batch never reaches the load step.

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

What is pandera used for?

pandera validates pandas (and Polars) DataFrames against a declared schema - column types, nullability, and value constraints like ranges, regex patterns, and allowlists. It raises SchemaErrors with a structured failure report when validation fails.

What does lazy=True do in pandera?

By default pandera raises on the first failing row. With lazy=True it runs every check on every row, then raises a single SchemaErrors that contains all failures in the failure_cases DataFrame - so you see every problem at once.

How do I validate CSV data with pandera?

Read the CSV with pd.read_csv, declare a pa.DataFrameSchema with coerce=True (to cast string columns to their declared dtype), and call schema.validate(df, lazy=True). Catch pa.errors.SchemaErrors and inspect e.failure_cases for the details.

Keep learning

Make an ETL Pipeline IdempotentData projectSpeed Up a Slow SQL Report QueryData projectMake a CSV Importer Resilient to Bad DataData projectData roadmapStep by step to hiredData interview questionsSTAR answersAll Data projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →