marshmallow-code / marshmallow-code/marshmallow

Validation for Dynamically Nested Schema doesnt seem to work

Open
#1,541 3 comments 1 reaction 0 assignees View on GitHub
polymorphism
Dominant language
Python
Stars
7.2k
Forks
738
Avg merge
1d 23h
Merged PRs (30d)
7

Description

Hello,
I recently upgraded Marshmallow to v3.

I have the incoming data in this format.
`{
"sync":"receiver",
"data":{
"receiver_id":123,
"receiver_name":"test_receiver"
}
}`

Based on the value of "sync" field, I chose different Serializers.

Here is my code snippet.

```
ALLOWED_SYNCS = ['tag', 'receiver', 'customer']
class ReceiverSerializer(Schema):
receiver_id = fields.Integer(required=True)
receiver_name = fields.String(required=True)

class CustomerSerializer(Schema):
customer_id = fields.Integer(required=True)
customer_name = fields.String(required=True)
customer_enabled = fields.Boolean(required=True)

class SyncSerializer(Schema):
SYNC_OBJECT_SERIALIZERS = {
'receiver': ReceiverSerializer,
'customer': CustomerSerializer
}
sync = fields.String(required=True, validate=validate.OneOf(ALLOWED_SYNCS))
data = fields.Dict(required=True)

def _get_sync_object_data(self, sync):
serializer = self.SYNC_OBJECT_SERIALIZERS.get(sync)

if not serializer:
return None

return fields.Nested(serializer)

@pre_load
def pre_load(self, data, **kwargs):
sync_object = data.get('sync')

if sync_object:
data['sync'] = sync_object.lower()

# Dynamically change config field type based on delivery type
sync_data = self._get_sync_object_data(sync_object)
if sync_data:
self.fields['data'] = sync_data

return data
```

If the payload is
```
payload = {
'sync': 'receiver',
'data': {
'receiver_name': 'Test'
}
}
sync_object = SyncSerializer().loads(json.dumps(payload))
```
It doesn't raise ValidationError because required field "receiver_id" is missing

Contributor guide

Open the contributing guide

Research direction

Reproduce the report with the shown payload and start in SyncSerializer.pre_load, especially the dynamic assignment to self.fields['data']. Trace how Marshmallow v3 applies the nested schema during loads; done when a missing receiver_id produces the expected ValidationError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.