How to Validate Data Before Scaling in Python

A reusable Python helper that validates required fields and constraint checks on data rows before entering a database pipeline, improving data quality and throughput.

Easy Python 3.9+ Aug 9, 2026 Database scaling & optimization 15 views 0 copies

Python code

44 lines
Python 3.9+
def validate_data(data, required_fields, constraints=None):
    """
    Basic validation helper demonstrating data-quality workflows
    before scaling (catches bad rows early, improves throughput).
    """
    constraints = constraints or {}

    errors = []
    for field in required_fields:
        if field not in data or data[field] == "" or data[field] is None:
            errors.append(f"Missing required field: {field}")

    for field, check in constraints.items():
        if field in data and data[field] is not None and data[field] != "":
            if not check(data[field]):
                errors.append(f"Invalid value for {field}: {data[field]!r}")

    return {"is_valid": not errors, "errors": errors}


def common_constraints():
    """Reusable validator functions for typical column types."""
    return {
        "age": lambda v: isinstance(v, int) and 0 <= v <= 150,
        "email": lambda v: "@" in v and "." in v.split("@")[-1],
        "score": lambda v: isinstance(v, (int, float)) and 0 <= v <= 100,
    }


if __name__ == "__main__":
    # Simulated incoming rows — one clean, one dirty
    rows = [
        {"name": "Alice", "age": 30, "email": "alice@example.com", "score": 85.5},
        {"name": "", "age": 300, "email": "bob_at_bad_domain", "score": "high"},
    ]

    required = ["name", "age", "email"]
    checks = common_constraints()

    # Fast pre-scaling validation loop
    for i, row in enumerate(rows, 1):
        result = validate_data(row, required, checks)
        status = "PASS" if result["is_valid"] else "REJECT"
        print(f"Row {i}: {status} -> {result['errors'] if result['errors'] else 'OK'}")

Output

stdout
Row 1: PASS -> OK
Row 2: REJECT -> ['Missing required field: name', 'Invalid value for age: 300', 'Invalid value for email: bob_at_bad_domain', 'Invalid value for score: high']

How it works

This helper runs validation before data hits your database, so bad rows are caught early—reducing writes and failures at scale. validate_data loops through required fields, emitting a missing-field error when the key is absent, empty, or None. For constraints, it applies provided check functions to present non-null values and records descriptive errors when checks fail. The result aggregates validity and errors into a single dict for easy use in batch or streaming pipelines. Using this pattern saves database I/O and avoids inserting invalid rows that later require cleanup or cause query anomalies.

Common mistakes

  • Forgetting that an empty string is treated as missing, which may be valid for some optional fields.
  • Assuming `constraints` values are callable; a non-callable check raises a `TypeError` during execution.
  • Not applying constraints to empty or None values, which can skip required checks in some datasets.

Variations

  1. Use `pydantic` models for schema-based validation with type coercion and custom validators.
  2. Leverage `cerberus` or `jsonschema` for more complex nested validation rules.

Real-world use cases

  • Cleaning records from CSV uploads before inserting into a production Postgres table, nipping malformed rows early.
  • Pre-filtering user signup payloads in an API gateway to reject invalid age or email before hitting your user service.
  • Validating event messages in a Kafka consumer before writing to a data warehouse, preventing corrupted analytics.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Database scaling & optimization

Related tutorials and quizzes for this topic.