Reputation: 803
I need to update the value for key (id
) in the JSON file. Value is stored in the variable ids
. I am able to update the key id
with ids
(updated value), but the structure of the JSON file gets messed up. Can anyone suggest me a way to doing it without messing up the JSON structure?
Code:
ids=10
filename='update_test.json'
with open(filename,'r') as f:
data=json.load(f)
data['id'] = ids
os.remove(filename)
with open(filename,'w') as f:
json.dump(data,f,indent=4)
Input JSON:
{
"accountableExecutiveTech": "string",
"api": true,
"arrivalFrequency": "string",
"bucketName": "string",
"businessDataset": "string",
"columns": [{
"businessColumnName": "string",
"childColumns": [{}],
"columnOrder": 0,
"description": "string",
"descriptiveName": "string",
"format": "string",
"hierarchicalName": "string",
"id": 0,
"isArray": true,
"length": 0,
"name": "string",
"parentColumnName": "string",
"partitionColumn": true,
"technicalDatasetId": 0,
"technicalDatasetName": "string",
"technicalNamespace": "string",
"technicalPlatformName": "string",
"type": "string",
"validValues": {}
}],
"controlMJobName": "string",
"credit": true,
"delimiter": "string",
"delimiterFlag": true,
"description": "string",
"dqPrioritized": true,
"fileFormat": "string",
"id": "",
"name": "string",
"namespace": "string",
"npi": true,
"objectKey": "string",
"pci": true,
"performingDataSteward": "string",
"platformName": "string",
"retentionPlan": "string",
"selectAdGroup": "string",
"sourceDatasets": [{
"id": 4534,
"name": "string",
"namespace": "string",
"platformName": "string"
}],
"tags": ["string"]
}
Output JSON:
{
"accountableExecutiveTech": "string",
"delimiterFlag": true,
"performingDataSteward": "string",
"api": true,
"dqPrioritized": true,
"id": 14044,
"namespace": "string",
"fileFormat": "string",
"selectAdGroup": "string",
"pci": true,
"platformName": "string",
"columns": [
{
"isArray": true,
"partitionColumn": true,
"description": "string",
"technicalDatasetId": 0,
"format": "string",
"technicalPlatformName": "string",
"parentColumnName": "string",
"columnOrder": 0,
"length": 0,
"childColumns": [
{}
],
"descriptiveName": "string",
"validValues": {},
"technicalDatasetName": "string",
"technicalNamespace": "string",
"hierarchicalName": "string",
"businessColumnName": "string",
"type": "string",
"id": 0,
"name": "string"
}
],
"businessDataset": "string",
"npi": true,
"description": "string",
"tags": [
"string"
],
"arrivalFrequency": "string",
"objectKey": "string",
"bucketName": "string",
"controlMJobName": "string",
"name": "string",
"retentionPlan": "string",
"credit": true,
"delimiter": "string",
"sourceDatasets": [
{
"platformName": "string",
"namespace": "string",
"id": 4534,
"name": "string"
}
]
Upvotes: 1
Views: 3125
Reputation: 18697
I'm guessing you're referring to the order of keys in you dictionary (later in serialized JSON) that gets changed. That's because by default json.load()
uses dict
as an underlaying mapping type.
But you can change that to a dictionary type that preserves order, called collections.OrderedDict
:
from collections import OrderedDict
ids = 10
filename = 'update_test.json'
with open(filename, 'r') as f:
data = json.load(f, object_pairs_hook=OrderedDict)
data['id'] = ids
with open(filename, 'w') as f:
json.dump(data, f, indent=4)
Note the use of object_pairs_hook=OrderedDict
in json.load()
. From the docs:
object_pairs_hook
is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of object_pairs_hook will be used instead of thedict
. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict() will remember the order of insertion).
Upvotes: 3