1

Is there a way to create a custom normalization rule in Cerberus?

I am using Cerberus to normalize Protobuf messages before storing them in MongoDB. One of my use cases is to flatten a sub-message to a reference:

{
    "team": {"id": {"value": "<some-id>"}, "random": "value"}
}

to

{
    "team": {"value": "<some-id>"}
}

My schema:

{
    'team': {
        'type': 'primarykey',
        'coerce': 'primarykey',
        'data_relation': {'schema': 0, 'field': 'id'},
        'required': True,
        'permanent': True,
    }
}

My coercer for 'primarykey' expects the second format so that it can convert the value. If I don't normalize before hand, it is impossible to know which key is the reference since all the coercer functions gets is the value.

Ideally, I would have a custom normalization function run for data_relation before the coercer is called. e.g. _normalize_data_relation.

Edit:

def _normalize_coerce_data_relation(self, value):
        # value is {"id": {"value": "<some-id>"}, "random": "value"}
        # however I do not know the value of the `field` key in
        # the data_relation rule since the only thing passed in
        # is the value itself.

I do not know if the data_relation in the schema is set to field: id or field: random, thus I do not know how to normalize.

Ideally what I would want is something similar to the validation rule where I get the value of the schema as well:

def _normalize_data_relation(self, relation, field, value):
    print(relation['field']) # 'id'
    return value[relation['field']]
dreftymac
  • 31,404
  • 26
  • 119
  • 182

1 Answers1

0

I'm not sure if I got your question correctly, but it may help you to point out, that you can define a coercer chain:

schema = {
    'team': {'coerce': ('data_relation', 'primarykey')}
}

given that your validator implements a _normalize_coerce_data_relation method.

funky-future
  • 3,716
  • 1
  • 30
  • 43
  • Thanks, yes I know about using coercer chains. My issue with that is a coercer is only given the value to coerce, not the context in which it is being coerced in regards to the schema. Given the value to coerce (the team dictionary for example), I would not know which field is referenced in the `data_relation` rule and thus which field needs to be "flattened". – Matthew Ellison Apr 30 '18 at 18:58
  • Could you please enhance your question with code examples that reflect that context? – funky-future May 01 '18 at 12:02