How to serialize SqlAlchemy result to JSON?

后端 未结 27 1984
说谎
说谎 2020-11-22 09:59

Django has some good automatic serialization of ORM models returned from DB to JSON format.

How to serialize SQLAlchemy query result to JSON format?

I tried

27条回答
  •  暖寄归人
    2020-11-22 10:25

    Custom serialization and deserialization.

    "from_json" (class method) builds a Model object based on json data.

    "deserialize" could be called only on instance, and merge all data from json into Model instance.

    "serialize" - recursive serialization

    __write_only__ property is needed to define write only properties ("password_hash" for example).

    class Serializable(object):
        __exclude__ = ('id',)
        __include__ = ()
        __write_only__ = ()
    
        @classmethod
        def from_json(cls, json, selfObj=None):
            if selfObj is None:
                self = cls()
            else:
                self = selfObj
            exclude = (cls.__exclude__ or ()) + Serializable.__exclude__
            include = cls.__include__ or ()
            if json:
                for prop, value in json.iteritems():
                    # ignore all non user data, e.g. only
                    if (not (prop in exclude) | (prop in include)) and isinstance(
                            getattr(cls, prop, None), QueryableAttribute):
                        setattr(self, prop, value)
            return self
    
        def deserialize(self, json):
            if not json:
                return None
            return self.__class__.from_json(json, selfObj=self)
    
        @classmethod
        def serialize_list(cls, object_list=[]):
            output = []
            for li in object_list:
                if isinstance(li, Serializable):
                    output.append(li.serialize())
                else:
                    output.append(li)
            return output
    
        def serialize(self, **kwargs):
    
            # init write only props
            if len(getattr(self.__class__, '__write_only__', ())) == 0:
                self.__class__.__write_only__ = ()
            dictionary = {}
            expand = kwargs.get('expand', ()) or ()
            prop = 'props'
            if expand:
                # expand all the fields
                for key in expand:
                    getattr(self, key)
            iterable = self.__dict__.items()
            is_custom_property_set = False
            # include only properties passed as parameter
            if (prop in kwargs) and (kwargs.get(prop, None) is not None):
                is_custom_property_set = True
                iterable = kwargs.get(prop, None)
            # loop trough all accessible properties
            for key in iterable:
                accessor = key
                if isinstance(key, tuple):
                    accessor = key[0]
                if not (accessor in self.__class__.__write_only__) and not accessor.startswith('_'):
                    # force select from db to be able get relationships
                    if is_custom_property_set:
                        getattr(self, accessor, None)
                    if isinstance(self.__dict__.get(accessor), list):
                        dictionary[accessor] = self.__class__.serialize_list(object_list=self.__dict__.get(accessor))
                    # check if those properties are read only
                    elif isinstance(self.__dict__.get(accessor), Serializable):
                        dictionary[accessor] = self.__dict__.get(accessor).serialize()
                    else:
                        dictionary[accessor] = self.__dict__.get(accessor)
            return dictionary
    

提交回复
热议问题