Attach Source File Metadata to Records in Python
Add a source filename field to each record in a list by merging a new key into every dictionary using a dict unpacking comprehension.
Python code
18 linesfrom pathlib import Path
import json
def attach_source_metadata(records, source_file):
"""Attach source filename metadata to each record."""
return [
{**record, "source": Path(source_file).name}
for record in records
]
if __name__ == "__main__":
source = "/data/raw/customers.csv"
sample_records = [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
enriched = attach_source_metadata(sample_records, source)
print(json.dumps(enriched, indent=2))
Output
[
{
"id": 1,
"name": "Alice",
"source": "customers.csv"
},
{
"id": 2,
"name": "Bob",
"source": "customers.csv"
}
]
How it works
The {**record, "source": Path(source_file).name} expression creates a new dictionary with all existing fields plus a source key set to the basename of the file. Using Path(source_file).name extracts just the filename without the directory path, which keeps lineage metadata clean and portable. The list comprehension iterates over the original records without mutating them, returning a new enriched list — important when the source data should remain untouched for audit trails. This pattern is a common building block in ETL pipelines where each row needs a traceable origin.
Common mistakes
- Mutating the original record with `record['source'] = ...` instead of returning a new dict
- Using the full file path instead of `Path(source_file).name`, which breaks portability across environments
- Forgetting that `**record` must come before the new key if you want the source field to override any pre-existing value
Variations
- Use a `dataclass` with a `from_record` constructor for typed records
- Add a timestamp alongside the source with `{**record, 'source': name, 'ingested_at': datetime.now().isoformat()}`
- Attach file metadata lazily using a generator expression for streaming large datasets
Real-world use cases
- Tagging records in a nightly data warehouse load with their raw source filename for lineage tracking and debugging.
- Enriching rows pulled from multiple CSV exports with the originating file so downstream analytics can segment by source.
- Adding provenance to log events or metrics batches so engineers can trace data quality issues back to the producing system.
Sponsored
More from Data pipelines & processing
- Add a UUID Surrogate Key to Each Row in a CSV with Python easy
- Build a Python Utility That Detects Duplicate Records Across Multiple Excel Sheets medium
- Check Null Rate Threshold in PySpark DataFrame medium
- Count Records Processed per Category in Python easy
- Create Data Helper Functions in Python for Beginners easy
- Deduplicate events by ID within a window in Python medium
Keep learning
Related tutorials and quizzes for this topic.