Add a UUID Surrogate Key to Each Row in a CSV with Python

Generate a unique UUID string for every row in a CSV file using the standard-library uuid and csv modules.

Easy Python 3.9+ Aug 9, 2026 Data pipelines & processing 14 views 0 copies

Python code

30 lines
Python 3.9+
import uuid
import csv

def add_surrogate_key(filename):
    with open(filename, newline='') as f_in:
        reader = csv.DictReader(f_in)
        rows = list(reader)

    for row in rows:
        row['surrogate_key'] = str(uuid.uuid4())

    with open(filename, 'w', newline='') as f_out:
        writer = csv.DictWriter(f_out, fieldnames=rows[0].keys())
        writer.writeheader()
        writer.writerows(rows)

if __name__ == "__main__":
    with open('temp_data.csv', 'w', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(['name', 'age'])
        writer.writerow(['Alice', 30])
        writer.writerow(['Bob', 25])

    add_surrogate_key('temp_data.csv')

    with open('temp_data.csv') as f:
        print(f.read())

    import os
    os.remove('temp_data.csv')

Output

stdout
name,age,surrogate_key
Alice,30,6f5e39b5-1b1a-4b5f-8d6a-3b3d0a2a9c7e
Bob,25,4c21f0d8-8c4d-4b2e-9a3f-5d8b6e7f1a2b

Process finished with exit code 0

How it works

The csv.DictReader maps each row into an ordered dictionary keyed by the header. Iterating over the rows and assigning str(uuid.uuid4()) adds a new key-value pair with a 128-bit random UUID. csv.DictWriter then rewrites the file with rows[0].keys() as the fieldnames, so the new column is appended in every row. Reading the whole file into a list first ensures the header order stays stable while you modify rows.

Common mistakes

  • Writing to the same file while reading it — always buffer rows or use a temp file.
  • Using `uuid.uuid4()` without `str()` and getting a UUID object instead of a string in the CSV.

Variations

  1. Write the output to a separate file instead of overwriting, using `with open(out_file, 'w')`.
  2. Generate a deterministic key by hashing existing columns, e.g. `hashlib.md5(row['email'].encode()).hexdigest()`.

Real-world use cases

  • Adding a stable primary key to imported legacy data before loading into a database.
  • Creating unique identifiers for event logs or ML training records that need row-level traceability.
  • Enriching CSV exports with an id suitable for distributed systems where auto-increment isn't safe.

Sponsored

Run this sample

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

Open editor

More from Data pipelines & processing

Related tutorials and quizzes for this topic.