views:

215

answers:

3

Reading the doc of sqlalchemy, i saw the serialization part.
I'm wondering about a possibility to use an xml serializer for matching sa models with Rest webservices like Jax-RS
There is a django extension which deal with that : django_roa
Do you know if that kind of thing has already been developped for sqlalchemy or if is it possible to do it??
Thanks

+1  A: 

sqlalchemy.ext.serializer exists to support pickling (with pickle module) of queries, expressions and other internal SQLAlchemy objects, it doesn't deal with model objects. In no way it will help you to serialize model objects to XML. Probably something like pyxser will be useful for you.

Denis Otkidach
ok i will check it, thank you
Jérôme Pigeot
A: 

After some researches i wrote a little app to shows what i want : http://bitbucket.org/ee_lars/resttest

The code is really ugly ...

The serialization is ok for classical fields (Integer, Unicode, Boolean..) but i didn't find the way to handle Foreign Keys and stuffs like that. I think it's possible to "detect" that a field is in a particular type (from the mapper of his Model) and then putting URI of the related model as a link in the serialized resource.

Anyway i have no idea on how to do that : any possibility/idea??? thanks.

Jérôme Pigeot
A: 

Its a long way till full RFC2616 compliance, but for a prototype, I do something like this:

from sqlalchemy import create_engine, Table, Column, Integer, String, ForeignKey, UniqueConstraint
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, backref, sessionmaker
from sqlalchemy.sql.expression import desc
import web
import json

DB_PATH = 'sqlite:////tmp/test.db'

Base = declarative_base()

class LocalClient(Base):
    __tablename__ = 'local_clients'
    __jsonexport__ = ['id', 'name', 'password']

    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True, nullable=False) 
    password = Column(String)

    def __init__(self, name, password):
        self.name = name
        self.password = password

    def __repr__(self):
        return "<LocalClient('%s', '%s')>" % (self.name, self.password)

urls = (
    '/a/LocalClient', 'LocalClientsController'
)

class Encoder(json.JSONEncoder):
    '''This class contains the JSON serializer function for user defined types'''
    def default(self, obj):
        '''This function uses the __jsonexport__ list of relevant attributes to serialize the objects that inherits Base'''
        if isinstance(obj, Base):
            return dict(zip(obj.__jsonexport__, [getattr(obj, v) for v in obj.__jsonexport__]))
        return json.JSONEncoder.default(self, obj)

class LocalClientsController:
    '''The generic RESTful Local Clients Controller'''
    def GET(self):
        '''Returns a JSON list of LocalClients'''
        engine = create_engine(DB_PATH, echo=False)
        Session = sessionmaker(bind=engine)
        session = Session()
        clis = session.query(LocalClient)
        return json.dumps([c for c in clis], cls=Encoder)
Marco