Consider this simplified scenario. Master-detail tables:
CREATE TABLE queue (
id bigint PRIMARY KEY,
num text NOT NULL UNIQUE
);
CREATE TABLE queue_device (
id bigint PRIMARY KEY,
queue_id bigint NOT NULL REFERENCES queue ON DELETE CASCADE,
device text NOT NULL,
UNIQUE (queue_id,device)
);
When adding devices, users obviously don't know the id
, they enter num
instead. So I tried this validation schema:
SCHEMA = {
'queue': {
'type': 'string',
'empty': False,
'required': True,
'rename': 'queue_id',
'coerce': 'queue_id'
},
'device': {
'type': 'string',
'empty': False,
'required': True
}
}
I wanted to rename the field and coerce it to proper value, but custom coercer does not get executed. I am sure there is a rationale for doing renaming before coercing, but I for one don't see it. This way, you effectively can't have both rename
and coerce
rules on same field.
OK, so I tried to set coercer on a renamed field, marking it readonly
because users must not set it directly.
SCHEMA = {
'queue': {
'type': 'string',
'empty': False,
'required': True,
'rename': 'queue_id'
},
'device': {
'type': 'string',
'empty': False,
'required': True
},
'queue_id': {
'readonly': True,
'coerce': 'queue_id'
}
}
I do the validation first, then normalization.
if not validator.validate(document, normalize=False):
raise ValidationError('Document validation failed.', validator.errors)
document = validator.normalized(document)
This fails because of the readonly
rule. Again, I wonder what is the rationale for checking readonly
during normalization, as this is a validation, not normalization rule.
I keep hitting a wall. What is the proper way to write a validation schema in this case?