Search code examples
pythonsqlalchemypsycopg2marshmallow

Marshmallow result customization


I have the sqlalchemy model with jsonb field and marshmallow schema for this model:

class Settings(db.Model):
    id = db.Column(UUID, primary_key=True,
                   server_default=text("uuid_generate_v4()"))
    settings = db.Column(JSONB)

class SettingsSchema(ma.ModelSchema):
    class Meta:
        model = Settings

I'm serializing it in json like:

settings = Settings(settings={'qwerty': 'test'})
settings_schema = SettingsSchema(many=False, exclude=('id', ))
body = settings_schema.dump(settings).data

and json view of the model looks like this:

{
  "settings": {
    "qwerty": "test"
  }
}

When I'm using this schema as nested I have result like

{
    "id": 123456,
    "some_field": "some_field_value",
    "other_field": "other_field_value",
    "settings": {
        "settings": {
            "qwerty": "test"
        }
    }
}

and this "settings.settings" looks ugly.

Is there a way said to marshmallow that I need only value as dump result, I mean

{
    "qwerty": "test"
}

Probably I need to do something with metaclasses, but I have no idea what should I do.


Solution

  • I've got it. I should been used @post_dump in my schema:

    class SettingsSchema(ma.ModelSchema):
    
        class Meta:
            model = WorkspaceSettings
    
        @post_dump(pass_many=True)
        def unwrap_settings(self, data, many):
    
            if many:
                return [item['settings'] or {} for item in data]
            else:
                return data['settings'] or {}