How to read a CSV file in Python and check its columns

Read a CSV export with Python's built-in tools, check required columns and row lengths, and catch common import mistakes without changing the original file.

Beginner5 min read
In this guide

Before you automate an export, check that Python is reading the right values under the right column names. A comma inside a product name should not move the rest of the row one column to the right.

This guide gives you a small checker that reads your CSV, confirms its required columns, and reports the number of records and empty cells. It leaves the original file unchanged. You can run it on your computer; you do not need a server, an account, or an extra Python package.

Get your file ready

You need Python 3.12 or newer already installed, a terminal, and a plain-text editor. On Windows, open PowerShell and run py --version. On macOS or Linux, open Terminal and run python3 --version. If neither command is available on your system, install Python using the official downloads page, reopen the terminal, and check again.

Create a folder named csv-check somewhere easy to find. Work with a copy of a small export while learning. A CSV is text arranged in records and cells. For this guide, its first row must contain column names. An .xlsx workbook is not a CSV: export a CSV copy from your spreadsheet app first.

Use your own UTF-8, comma-separated CSV with a header, or save this fictional example as orders.csv inside the folder:

order_id,item,quantity
1001,"Notebook, blue",2
1002,Café mug,1
1003,Pen,

Save as plain text, not a word-processing document. In Windows Notepad’s Save As dialog, choose All files, use the exact filename, and select UTF-8 so it does not become orders.csv.txt.

The quotation marks keep Notebook, blue in one cell. The last row has a genuinely empty quantity. The checker should preserve both facts, not silently repair them.

Save the checker

Create check_csv.py in the same folder and paste the complete script below. Save it as UTF-8 plain text too.

import argparse
import csv
import sys

sys.stdout.reconfigure(errors="backslashreplace")

parser = argparse.ArgumentParser(description="Check a CSV without changing it.")
parser.add_argument("file")
parser.add_argument("--columns", nargs="+", required=True)
args = parser.parse_args()

try:
    with open(args.file, encoding="utf-8-sig", newline="") as source:
        reader = csv.reader(source, strict=True)
        header = next(reader, None)
        if not header or any(not name.strip() for name in header):
            raise ValueError("The first row must contain non-empty column names.")
        if len(header) != len(set(header)):
            raise ValueError("Column names must be unique.")
        missing = [name for name in args.columns if name not in header]
        if missing:
            raise ValueError(f"Missing required columns: {missing}")

        count = empty = 0
        first = None
        for row in reader:
            if not row:  # Ignore completely blank lines.
                continue
            if len(row) != len(header):
                raise ValueError(f"Wrong cell count near line {reader.line_num}.")
            count += 1
            empty += sum(value == "" for value in row)
            if first is None:
                first = dict(zip(header, row))

    print(f"Columns: {header}")
    print(f"Records: {count}; empty cells: {empty}")
    print(f"First record: {first}")
except (OSError, UnicodeError, csv.Error, ValueError) as error:
    sys.exit(f"Check failed: {error}")

Python’s csv module handles quoted cells. utf-8-sig accepts ordinary UTF-8 and the small encoding marker some spreadsheet exports add at the start. Neither setting guesses a different delimiter or repairs damaged data.

Run it against the columns you expect

In the terminal, enter cd "your folder path", replacing the words inside the quotes with the full path to csv-check. Keep the quotes if the path contains spaces. For example, a Windows path might be C:\Users\Sam\Documents\csv-check.

Run this command. On Windows, replace python3 with py in this guide’s commands:

python3 check_csv.py orders.csv --columns order_id item quantity

For your own file, replace orders.csv and the names after --columns. Those are the columns your next task needs; additional columns are allowed. Names are case-sensitive. Put a name containing spaces inside quotes, such as "Order ID".

The example produces:

Columns: ['order_id', 'item', 'quantity']
Records: 3; empty cells: 1
First record: {'order_id': '1001', 'item': 'Notebook, blue', 'quantity': '2'}

Check the first record against the source. Notebook, blue should be one item, and the row count should exclude the header. Python reads these values as text: the displayed '2' is not yet a number for arithmetic. If your terminal cannot display a character, the report uses an escape such as \xe9 for é; the file’s contents stay unchanged.

An empty-cell count is a prompt to inspect the file, not proof of an error. A blank note may be fine; a blank order quantity may need attention. A header-only file reports zero records, which is not a useful export if you expected orders.

If the check stops

  • Missing required columns: compare the first row with your command, including spaces and capitalization. If everything appears as one long column, the export probably uses semicolons or tabs. Re-export a comma-separated copy instead of replacing punctuation throughout the file.
  • Wrong cell count or a CSV error: inspect the reported area in a text editor. A comma inside a value needs CSV quotation marks. A quoted cell can span several physical lines, so the reported line is a location hint, not a record number.
  • An encoding error: re-export the file as UTF-8. Do not discard unreadable characters just to make the check pass.
  • File not found: confirm the terminal’s folder and the exact filename, including a possible extra .txt extension.

A successful check confirms structure, not the truth of your data. It does not validate quantities, detect repeated orders, or decide whether an empty value is acceptable.

You now have a repeatable first check before an import. To combine exports next, use the CSV merge guide. To deal with repeated records, use the duplicate-checking guide.

← Back to automation guides