Back to BlogsPython

Python CSV Validation: Build a Row-by-Row Error Report

Anuj Singh (Admin) 14 September 2026 22 views

A CSV file can open successfully and still contain unusable data. A blank customer name, a negative quantity or a text value in a numeric column can silently distort a report. The first goal of a validator is to explain which row failed and why, while preserving the original file for investigation.

Define the contract before reading rows

For this exercise, each row needs a name and an integer quantity of zero or more. Zero is valid; an empty value is not. These are business rules, not properties that the CSV format enforces. Write the rules down before deciding whether to reject, repair or quarantine bad rows.

import csv
from io import StringIO

sample = StringIO("name,quantity\nAsha,3\n,2\nRavi,abc\nMina,-1\n")
errors = []
valid = []
for row_number, row in enumerate(csv.DictReader(sample), start=2):
    reasons = []
    if not (row.get("name") or "").strip():
        reasons.append("name is missing")
    try:
        quantity = int(row.get("quantity") or "")
        if quantity < 0:
            reasons.append("quantity is negative")
    except ValueError:
        reasons.append("quantity is not an integer")
    if reasons:
        errors.append({"row": row_number, "errors": reasons})
    else:
        valid.append(row)
print(len(valid), len(errors))  # 1 3

Keep parsing separate from repair

The example labels the header as line 1 and begins data rows at 2. It catches conversion errors for individual rows rather than stopping the whole import. It deliberately does not turn invalid quantities into zero: that would make missing data indistinguishable from an actual zero quantity. With quoted multiline fields, a CSV record number is not necessarily the physical line number.

Use the report to make an import decision

For an actual file, open it with an explicit encoding and newline="" as recommended by the csv documentation. Confirm the header names before processing rows, then decide whether any error should block the entire import. Keep a separate report containing a record identifier and validation messages; avoid copying unnecessary personal information into logs.

Common mistake: testing only a good file

A validator that accepts one clean file has not demonstrated its rejection behavior. Test whitespace-only names, missing columns, an empty file and quantities such as 3.5. Decide whether surrounding whitespace, leading zeros and plus signs are permitted. Document those choices so a later change does not quietly alter the contract.

Practice and check your understanding

Add a required item_code column and reject duplicate codes within the input. Produce separate counts for accepted rows, invalid rows and duplicates. Test quantity 0 and confirm it remains valid.

Continue learning

Explore the related Code Hacker course syllabus for structured learning. Then read Python Exception Handling for a Reliable Import Pipeline to connect this exercise to the next skill.

Reference

Python csv module provides the underlying API or technical guidance. Check the documentation for the version you use; examples here are small learning exercises rather than complete production implementations.

Found an issue with this guide? Send a correction with the article URL and your example. About our learning material.

Topics in this article

  • python
  • csv
  • data validation
  • error handling

Want to Learn This Practically?

Subscribe to Code Hacker and get hands-on access to 40+ premium courses — Ethical Hacking, Kali Linux, Metasploit, Network Hacking, Bug Bounty & more!