简体   繁体   中英

Merge json files in Python

I'm trying to merge 2 json files in Python. Here are the files:

test1.json

{
    "version": "1.0",
    "data": {
        "admin1": {
            "id": "1",
            "location": "NY"
        },
        "admin2": {
                "id": "2",
                "name": "Bob",
                "location": "LA",
                "admin_key": {
                    "adminvalue1": "admin1",
                    "adminvalue2": "admin2"
                }
        },
        "admin3": {
            "name": "john"
        }
    }
}

test2.json

{
    "data": {
        "user1": {
            "name": "jane",
            "phone": "555-666-7777",
            "enail": "jane@jane.com"
        },
        "user2": {
            "location": "LA",
            "id": "5"
        },
        "user3": {
            "description": "user",
            "location": "NY",
            "name": "zoe",
            "phone": "111-222-3333",
            "user_key": {
                "uservalue1": "user1",
                "uservalue2": "user2"
            }
        }
    }
}

I have this code to merge the two files

import json

with open("test1.json", "r") as data1_file:
    data1 = json.load(data1_file)

with open("test2.json", "r") as data2_file:
    data2 = json.load(data2_file)

data1.update(data2)

with open("out.json", "w") as out_file:
    json.dump(data1, out_file, indent=4)

The output I'm getting is this. It only has test2.json contents under "data".

{
    "version": "1.0",
    "data": {
        "user1": {
            "name": "jane",
            "phone": "555-666-7777",
            "enail": "jane@jane.com"
        },
        "user2": {
            "location": "LA",
            "id": "5"
        },
        "user3": {
            "description": "user",
            "location": "NY",
            "name": "zoe",
            "phone": "111-222-3333",
            "user_key": {
                "uservalue1": "user1",
                "uservalue2": "user2"
            }
        }
    }
}

I want the output to have contents of both files under "data" like below

{
    "version": "1.0",
    "data": {
        "admin1": {
            "id": "1",
            "location": "NY"
        },
        "admin2": {
                "id": "2",
                "name": "Bob",
                "location": "LA",
                "admin_key": {
                    "adminvalue1": "admin1",
                    "adminvalue2": "admin2"
                }
        },
        "admin3": {
            "name": "john"
        },
        "user1": {
            "name": "jane",
            "phone": "555-666-7777",
            "enail": "jane@jane.com"
        },
        "user2": {
            "location": "LA",
            "id": "5"
        },
        "user3": {
            "description": "user",
            "location": "NY",
            "name": "zoe",
            "phone": "111-222-3333",
            "user_key": {
                "uservalue1": "user1",
                "uservalue2": "user2"
            }
        }
    }
}

How can I achieve this? Thanks!

You need to merge the "sub-dictionary" data1['data'] , not data1 itself. In the current code, you are updating data1 with data2 , so that data2['data'] overwrites data1['data'] .

So replace data1.update(data2) with:

data1['data'].update(data2['data'])

I think this is what you are looking for: https://stackoverflow.com/a/7205107/8786297

def merge(a, b, path=None):
    "merges b into a"
    if path is None: path = []
    for key in b:
        if key in a:
            if isinstance(a[key], dict) and isinstance(b[key], dict):
                merge(a[key], b[key], path + [str(key)])
            elif a[key] == b[key]:
                pass  # same leaf value
            else:
                raise Exception('Conflict at %s' % '.'.join(path + [str(key)]))
        else:
            a[key] = b[key]
    return a

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM