I have a master JSON ‘template’ that users export and fill in values.
They can also add (duplicate/update) objects within any number of arrays.
I now need to add a new element to all the objects within a particular array – so need to ‘push’ that revised object definition into all the user copies.
Am trying to do that with the jsonmerge library, but struggling to understand the docs to do what I need.
Below, the user data is in “data” json, and each object under ‘Flower’ has the properties “Size” & “Colour”
My master (“mstr”) has now been updated to add a 3rd property “xtra”.
I need that “xtra” to appear in all of the user’s “Flowers”
However, no matter which merge strategy I try – it just seems to be putting all of the flower items/objects into 1 array, but not updating their content with the new attribute.
Am I misunderstanding what the library’s function is – or am I just using it wrong ?
If anyone can clarify, would be grateful !
Thanks
import json
from jsonmerge import Merger
schema = {
"properties":{
"tree":{
"type":"array",
"mergeStrategy": "append"
}
},
"additionalProperties":False
}
mstr = {
"tree": [
{
"Name": "",
"Bud": {
"Flower": [
{
"Size": "",
"Colour": "",
"xtra":""
}
]
}
}
]
}
data = {
"tree": [
{
"Name": "",
"Bud": {
"Flower": [
{
"Size": "green",
"Colour": ""
},
{
"Size": "red",
"Colour": ""
}
]
}
}
]
}
merger = Merger(schema)
result = merger.merge(data,mstr)
print(result)
Result
{
"tree": [
{
"Name": "",
"Bud": {
"Flower": [
{
"Size": "",
"Colour": "",
"xtra": ""
}
]
}
},
{
"Name": "",
"Bud": {
"Flower": [
{
"Size": "green",
"Colour": ""
},
{
"Size": "red",
"Colour": ""
}
]
}
}
]
}
Update the document’s json schema using master schema definition
SiBush is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
The append
merge strategy for the tree
array simply adds the elements from the second JSON (mstr) to the end of the array in the first JSON (data). It doesn’t try to merge the contents of individual objects within the array.
def custom_merge_flower(base, head, schema):
result = {**head, **base}
if 'xtra' not in result:
result['xtra'] = ''
return result
schema = {
"properties": {
"tree": {
"type": "array",
"mergeStrategy": "arrayMergeById",
"mergeOptions": {"idRef": "/Name"}
}
},
"additionalProperties": False
}
flower_schema = {
"mergeStrategy": "objectMerge",
"mergeOptions": {
"customMerge": custom_merge_flower
}
}
mstr = {
"tree": [
{
"Name": "Tree1",
"Bud": {
"Flower": [
{
"Size": "",
"Colour": "",
"xtra": ""
}
]
}
}
]
}
data = {
"tree": [
{
"Name": "Tree1",
"Bud": {
"Flower": [
{
"Size": "green",
"Colour": "blue"
},
{
"Size": "red",
"Colour": "yellow"
}
]
}
}
]
}
merger = Merger(schema)
merger.schema['properties']['tree']['items'] = {
"properties": {
"Bud": {
"properties": {
"Flower": {
"type": "array",
"items": flower_schema
}
}
}
}
}
result = merger.merge(data, mstr)
print(json.dumps(result, indent=2))
The output#
{
"tree": [
{
"Name": "Tree1",
"Bud": {
"Flower": [
{
"Size": "green",
"Colour": "blue",
"xtra": ""
},
{
"Size": "red",
"Colour": "yellow",
"xtra": ""
}
]
}
}
]
}
1