cwacek/python-jsonschema-objects

Feature/Question: Adding Records to Array Objects

Closed this issue · 4 comments

What are you trying to do?
I have a schema which has a list of other objects in it. This is read in and recognized as an item by the library as type=='array', and the array of typed objects are under the 'data' attribute.

Do you have an idea about how this should work?

I'd like to be able to programmatically add new elements to the array. I may be missing something - likely am - but don't see how I can ask the object to let me initalize a new object of the list element, so that I can add it.

For example:
Data has:

"itemList":
   .type = 'array'
   .data = [
      <item name='example', id=56>
   ]

I wish to programatically add to the itemList array to add:
<item name='another', id=59>

Is there a generator/init accessible that I'm missing somewhere?

This feature or capability is also important for me as instances of the array need to be dynamically updated.

The way you do this is by setting the item validation to a reference in the schema so it gets a named object. You can then instantiate that object and add it to the array.

You can also do this with the anonymous object, but if the array item type is complicated (i.e. an object) that isn't going to be as obvious.

See an example of how this works here (specifically line 178):

def test_arrays_can_have_reffed_items_of_mixed_type():
schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"$id": "test",
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"oneOf": [
{"$ref": "#/definitions/foo"},
{
"type": "object",
"properties": {"bar": {"type": "string"}},
"required": ["bar"],
},
]
},
}
},
"definitions": {"foo": {"type": "string"}},
}
builder = pjs.ObjectBuilder(schema)
ns = builder.build_classes()
x = ns.Test(list=["foo", "bar"])
ns.Test(list=[{"bar": "nice"}, "bar"])
with pytest.raises(pjs.ValidationError):
ns.Test(list=[100])
assert x.list == ["foo", "bar"]
x.list.append(ns.Foo("bleh"))
assert x.list == ["foo", "bar", "bleh"]

I just added a fix to handle an instantiation error I saw when making sure that example worked, as part of the linked PR.

Fix included in 0.5.3.

Thanks, really appreciate the pointer and the fix, working great. I am inferring the type name and using getattr to get it from the schema, there is probably a place in the special vars to grab that name from (e.g., in the list, vs inferring it), but it's working fine as is for now.