Simple way of serializing an SQLAlchemy Model to a dict including relations

  |   Source

I am writing on a small Python Web Application Project in combination with SQLAlchemy.

I was also in need of serializing SQLAlchemy DB Models (declarative_base ones), so first I wrote an instance method as_dict() and caught all self.__table__.columns and converted them into a dict with the column name as key.

Sadly, what I didn't catch, that relational attributes are not belonging to the __table__.column space.

I should have consulted Google first, before I writing my own code.

I found this answer on StackOverflow for this question

class Serializer(object):
    __public__ = None

    def to_serializable_dict(self):
        dict = {}
        for public_key in self.__public__:
            value = getattr(self, public_key)
            if value:
                dict[public_key] = value
        return dict

And to enable it for my table model, this is how it goes:

class VServer(BaseModel, Serializer):
    __tablename__ = 'vserver_binding'
    __public__ = ['id', 'certkey', 'vserver', 'last_seen']

    id = Column(BigInteger, primary_key=True)
    certkey_id = Column(BigInteger, ForeignKey(''))
    vserver = Column(String)
    last_seen = Column(DateTime)
    certkey = relationship('CertKey')

    def as_json(self):
        return json.dumps(self.to_serializable_dict(), cls=ModelEncoder)

And for rendering to the page, I use something like this:

class PageVServers(RESTController):
    def _index(self, *args, **kwargs):
        verb = kwargs.get('verb', None)
        page = Page(verb['template'], web.ctx.tmpl_environment, context=web.ctx)
        q = web.ctx.orm.query(VServer)
        datalist = [i.to_serializable_dict() for i in q.order_by(VServer.last_seen).all()]
        return page.render()

RESTController and Page are classes of my Framework, which will be released later this year.