Reputation: 1425
So I'm using Cerberus for schema validation, but I'm running into a particular with validating a subdictionary of a dictionary whose key is unknown.
So say I have the following document:
dict = {
'things': {
'0463': {
'foo': 'blah',
'bar': 'bleep'
},
'0464': {
'foo': 'x',
'bar': 'y'
},
'another_random_id': {
'foo': 'blah',
'bar': 'bleep'
}
}
So i want to validate that the subdictionaries have a specific structure (foo
and bar
as keys), but I can't figure out a way to validate this without knowing the keys ahead of time (which in my case are random id's. I figured this was a good use of valueschema but i can't seem to get valueschema to work with something of type 'dict'. I tried to set the following schema in cerberus:
schema = {
'things': {
'type': 'dict',
'valueschema': {
'type': 'dict',
'foo': {'type': 'string'},
'bar': {'type': 'string'}
}
}
}
Am i defining my schema incorrectly or is this not possible with the current implementation of valueschema
. I saw some tests in the repository that used valueschema
, but they were only testing where the type of valueschema
was an int or a string.
Upvotes: 4
Views: 2713
Reputation: 1425
So I figured out that cerberus will handle valueschema
if it's of type dict
if I put a schema
field after the valueschema
key. So my structure should be:
schema = {
'things': {
'type': 'dict',
'valueschema': {
'type': 'dict',
'schema':{
'foo': {'type': 'string'},
'bar': {'type': 'string'}
}
}
}
}
Now there's still some weirdness because it doesn't seem like valueschema
was designed with the expectation that it would validate a value of type dict
. For example when I extend from the validator, I had to override the validate_valueschema
method so that the required
validation acts the same as it would for a regular schema, because when it calls validate
on the schema it doesn't pass in the update
parameter. So my overridden validate_valueschema
looks like this:
def _validate_valueschema(self, schema, field, value):
if isinstance(value, Mapping):
for key, document in value.items():
validator = self._Validator__get_child_validator()
validator.validate(
{key: document}, {key: schema},
context=self.document, update=self.update)
if len(validator.errors):
self._error(field, validator.errors)
The update=self.update
is all I added.
Upvotes: 4