Compare two CSV header shapes before an import migration

Quick answer

Compare two parsed CSV header records before a migration reads any data rows. Parsing each header with csv.reader keeps quoting and delimiter interpretation consistent with the planned import, while a plain hard-coded list would only test the comparison logic.

Example

read_header obtains the first record from each CSV fixture. The comparison then reports labels present only in the old shape and labels present only in the new shape. The assertion proves the normal parsing path and the concrete rename-shaped result: email was removed and contact_email was added. It does not claim they are semantically interchangeable.

import csv
import io


def read_header(text):
    return next(csv.reader(io.StringIO(text, newline="")))


old = read_header("id,email,name\n")
new = read_header("id,contact_email,name\n")
removed = [name for name in old if name not in new]
added = [name for name in new if name not in old]

assert old == ["id", "email", "name"]
assert (removed, added) == (["email"], ["contact_email"])
print(f"removed={removed} added={added}")

Expected stdout:

removed=['email'] added=['contact_email']

Reading the result

This comparison is set-like with respect to order: it detects additions and removals, but not an id,name,email reorder. Add a sequence comparison when a downstream consumer indexes fields by position. Check duplicate raw headers separately as well, because membership comparisons do not expose which repeated position a mapper would choose.

A migration owner may decide that contact_email replaces email, but that is a documented mapping decision, not a name-similarity heuristic. The header preflight should surface the difference early and leave the migration rule explicit.

Sources

- Python csv.reader documentation

Prepared with AI assistance. The example uses synthetic data; its stated limits apply.

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic