Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polymorphism for schema #192

Open
fangpenlin opened this issue Sep 16, 2014 · 10 comments
Open

Polymorphism for schema #192

fangpenlin opened this issue Sep 16, 2014 · 10 comments

Comments

@fangpenlin
Copy link

We have a scenario, say you have a message schema

class MessageSchema(colander.MappingSchema):
    header = EventHeader()
    payload = Payload()

For the payload, you can define it like this

class Payload(colander.MappingSchema):
    type = colander.SchemaNode(colander.String())
    # and other attributes ...

It works fine if you can define all possible fields to the payload schema, however, in many cases, you simply can't. A better way is to define subclasses. Here we let Log inherits Payload

class Log(Payload):
    message = colander.SchemaNode(colander.String())
    severity = colander.SchemaNode(colander.String(), validators=[
        colander.OneOf((
            'debug',
            'info',
            'warning',
            'error',
        ))
    ])

By doing that, when you do serializing or deserializing, the payload = Payload() is still there in MessageSchema, so there is no way it can know which subclass schema to use. To solve that problem, we will need to have something like the polymorphism mechanism like the one from SQLAlchemy:

class MyClass(Base):
    __tablename__ = 'my_table'
    id = Column(Integer, primary_key=True)
    type = Column(String(50))
    alt = Column("some_alt", Integer)

    __mapper_args__ = {
        'polymorphic_on' : type
    }

http://docs.sqlalchemy.org/en/rel_0_9/orm/mapper_config.html#class-mapping-api

For colander, that could be something like

class Payload(AbstractSchema):
    type = colander.SchemaNode(colander.String())
    __mapper_args__ = {
        'polymorphic_on': 'type',
    }

class Log(Payload):
    type = 'log'
    message = colander.SchemaNode(colander.String())
    severity = colander.SchemaNode(colander.String(), validators=[
        colander.OneOf((
            'debug',
            'info',
            'warning',
            'error',
        ))
    ])

I will submit a pull request for this soon

fangpenlin added a commit to fangpenlin/colander that referenced this issue Sep 16, 2014
@fangpenlin
Copy link
Author

what do you guys think about this?

@jaseemabid
Copy link
Contributor

@victorlin Can you provide a failing test case to solidify the idea?

@tisdall
Copy link
Contributor

tisdall commented Jul 13, 2015

I really like this idea. I'm working on implementing a standard using JSON that does this very thing. It has one attribute that defines the type and the rest of the attributes can be validated depending on that "type" value.

@antolantic
Copy link

Great job @fangpenlin , I am surprised that the fix #192 has not been pull requested ?
It's a really needed feature for colander, any chance to merge it into trunk ?

@tseaver
Copy link
Member

tseaver commented Sep 6, 2017

@antolantic there is no PR yet for the work @fangpenlin has done on her fork.

@fangpenlin
Copy link
Author

@tseaver @antolantic Hi guys, I am not currently working on any project that's based on colander, and I don't have time to work on it now. You're very welcome to continue my previous work.

@antolantic
Copy link

Should I fork the @fangpenlin repo and make a PR then ?

@mmerickel
Copy link
Member

An administrative note: At the very least all of the commit authors need to have put their names into contributors.txt before anyone will consider merging such a PR into the official colander repo.

@fangpenlin
Copy link
Author

@mmerickel I've added my name to contributors on top of my original branch

fangpenlin@3a01216

does it help?

@antolantic
Copy link

@fangpenlin : could you initiate the PR ?

mvaled added a commit to mvaled/colander that referenced this issue Nov 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants