How to Implement a PATCH Partial Update Merge Dict in Python
Implements a recursive merge function that applies HTTP PATCH-like partial updates to a nested dictionary while preserving untouched fields.
Python code
17 linesimport json
def patch_merge(target: dict, patch: dict) -> dict:
"""Simulate HTTP PATCH semantic: shallow-merge patch into a copy of target."""
merged = target.copy()
for key, value in patch.items():
if isinstance(value, dict) and isinstance(merged.get(key), dict):
merged[key] = patch_merge(merged[key], value) # recursive nested merge
else:
merged[key] = value # overwrite or add
return merged
if __name__ == "__main__":
original = {"name": "Widget", "specs": {"color": "red", "size": 10}, "price": 5}
partial = {"specs": {"color": "blue"}, "in_stock": True}
result = patch_merge(original, partial)
print(json.dumps(result, indent=2))
Output
{
"name": "Widget",
"specs": {
"color": "blue",
"size": 10
},
"price": 5,
"in_stock": true
}
How it works
The function starts by copying the target dictionary so the original is never mutated. It then iterates over each patch key-value pair. If both the patch value and the existing target value are dictionaries, it recursively merges them so nested fields that aren't mentioned in the patch are kept. Otherwise, the patch value overwrites the target value or is added as a new key. This mirrors the semantic of a REST PATCH request where missing fields in the payload are left unchanged. The depth-first recursion handles arbitrarily nested structures correctly.
Common mistakes
- Mutating the original dict by using `merged = target` instead of `target.copy()`.
- Using a shallow merge (`{**target, **patch}`) which replaces nested dicts entirely.
- Forgetting to handle non-dict values in nested patches like lists or primitives.
Variations
- Use `copy.deepcopy(target)` if the target contains mutable objects like lists that should be cloned too.
- Use the `dpath` library for path-based merging with dot-notation key updates.
Real-world use cases
- Applying partial updates from a client to a resource in an API backend without losing existing nested fields.
- Patching representation state transfer (REST) resources in microservices where only some attributes change in a request.
- Syncing configuration files or settings where a user sends only changed sub-sections to avoid overwrites.
Sponsored
More from API design & gRPC
- Build a Bulk Array POST Mock Server in Python medium
- Build a Mock REST API with PUT and GET in Python medium
- Convert Protobuf to JSON and Dict in Python easy
- Create a Data Helper in Python for gRPC-style APIs easy
- Format data in Python using dataclasses like gRPC messages easy
- Generate an OpenAPI Spec from Mock Routes in Python easy
Keep learning
Related tutorials and quizzes for this topic.