0

So, I've to serialize something as simple as this:

[{'username': u'username', '_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x1d0e150>, 'updated_time_stamp': datetime.datetime(2013, 9, 23, 13, 38, 30, 775805), 'time_stamp': datetime.datetime(2013, 9, 23, 13, 38, 30, 775787), 'password': u'password', 'type': 'guru', 'id': 1}, {'username': u'satyajit', '_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x1d0e610>, 'updated_time_stamp': datetime.datetime(2013, 9, 24, 8, 43, 55, 940195), 'time_stamp': datetime.datetime(2013, 9, 24, 8, 43, 55, 940188), 'password': u'$2a$12$Y7zcWXM1et3At.fdzzMZNV8eHpEjnYIdKbZl/wNNtaGW6G3cYVkp6OS', 'type': 'guru', 'id': 2}]

It is a list, but has time stamp, and a _sa_instance_state attribute which json.dumps refuses to serialize popping up an error.

Thus I thought of writing my own serializer and came across a SO solution for it:

class PythonObjectEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (list, dict, str, unicode, int, float, bool, type(None))):
            return JSONEncoder.default(self, obj)
        return {'_python_object': pickle.dumps(obj)}

def as_python_object(dct):
    if '_python_object' in dct:
        return pickle.loads(str(dct['_python_object']))
    return dct

When I do run it, now I get this:

"[[{\"_python_object\": \"ccopy_reg\\n_reconstructor\\np0\\n(copentrade.libs.user.models\\nUserModel\\np1\\nc__builtin__\\nobject\\np2\\nNtp3\\nRp4\\n(dp5\\nS'username'\\np6\\nVusername\\np7\\nsS'_sa_instance_state'\\np8\\ng0\\n(csqlalchemy.orm.state\\nInstanceState\\np9\\ng2\\nNtp10\\nRp11\\n(dp12\\nS'class_'\\np13\\ng1\\nsS'modified'\\np14\\nI00\\nsS'committed_state'\\np15\\n(dp16\\nsS'instance'\\np17\\ng4\\nsS'callables'\\np18\\n(dp19\\nsS'key'\\np20\\n(g1\\n(I1\\ntp21\\ntp22\\nsS'expired'\\np23\\nI00\\nsbsS'updated_time_stamp'\\np24\\ncdatetime\\ndatetime\\np25\\n(S'\\\\x07\\\\xdd\\\\t\\\\x17\\\\r&\\\\x1e\\\\x0b\\\\xd6}'\\np26\\ntp27\\nRp28\\nsS'time_stamp'\\np29\\ng25\\n(S'\\\\x07\\\\xdd\\\\t\\\\x17\\\\r&\\\\x1e\\\\x0b\\\\xd6k'\\np30\\ntp31\\nRp32\\nsS'password'\\np33\\nVpassword\\np34\\nsS'type'\\np35\\nS'guru'\\np36\\nsS'id'\\np37\\nI1\\nsb.\"}, {\"_python_object\": \"ccopy_reg\\n_reconstructor\\np0\\n(copentrade.libs.user.models\\nUserModel\\np1\\nc__builtin__\\nobject\\np2\\nNtp3\\nRp4\\n(dp5\\nS'username'\\np6\\nVsatyajit\\np7\\nsS'_sa_instance_state'\\np8\\ng0\\n(csqlalchemy.orm.state\\nInstanceState\\np9\\ng2\\nNtp10\\nRp11\\n(dp12\\nS'class_'\\np13\\ng1\\nsS'modified'\\np14\\nI00\\nsS'committed_state'\\np15\\n(dp16\\nsS'instance'\\np17\\ng4\\nsS'callables'\\np18\\n(dp19\\nsS'key'\\np20\\n(g1\\n(I2\\ntp21\\ntp22\\nsS'expired'\\np23\\nI00\\nsbsS'updated_time_stamp'\\np24\\ncdatetime\\ndatetime\\np25\\n(S'\\\\x07\\\\xdd\\\\t\\\\x18\\\\x08+7\\\\x0eX\\\\xa3'\\np26\\ntp27\\nRp28\\nsS'time_stamp'\\np29\\ng25\\n(S'\\\\x07\\\\xdd\\\\t\\\\x18\\\\x08+7\\\\x0eX\\\\x9c'\\np30\\ntp31\\nRp32\\nsS'password'\\np33\\nV$2a$12$Y7zcWXM1et3At.fdMZNV8eHpEjnYIdKbZl/wNNtaGW6G3cYVkp6OS\\np34\\nsS'type'\\np35\\nS'guru'\\np36\\nsS'id'\\np37\\nI2\\nsb.\"}]]"

I'm a bit confused as to why this is happening and how to get rid of this error and serialize it properly. Any help?

Edit:

This is what I get when I'm trying to return a list of users from a UserModel declared using SQLAlchemy.

 File "/usr/lib/python2.7/dist-packages/simplejson/encoder.py", line 202, in default
    raise TypeError(repr(o) + " is not JSON serializable")

This happens while serializing the exact same data which I mentioned at the top, whose type is a list.

@cherrypy.tools.json_out()
def GET(self, account=None, request_type=None):
    #return the order list for this account type
    user = User()
    usermodel = user.get_all()
    #j = dumps(usermodel, cls=PythonObjectEncoder)
    return usermodel

This is how I'm returning the data. Currently I've commented out the PythonObjectEncoder, as it doesn't help my cause.

Hick
  • 35,524
  • 46
  • 151
  • 243
  • Why do you want to serialize the InstanceState? Also, what error are you talking about? That information is just pickle data, which will allow you to deserialize it. – Wayne Werner Oct 03 '13 at 15:30
  • I get this error: File "/usr/lib/python2.7/dist-packages/simplejson/encoder.py", line 202, in default raise TypeError(repr(o) + " is not JSON serializable") – Hick Oct 03 '13 at 15:45
  • Might want to add that to your question - and if you can come up with a small example that would also be awesome. – Wayne Werner Oct 03 '13 at 15:47
  • Have edited my question. – Hick Oct 03 '13 at 15:55
  • possible duplicate of [How to serialize SqlAlchemy result to JSON?](http://stackoverflow.com/questions/5022066/how-to-serialize-sqlalchemy-result-to-json) – Wolph Oct 03 '13 at 15:59

1 Answers1

0

It's possible that you might not actually want to serialize the entire model.

One approach is to do something like so:

class MyModel(Base):
    __tablename__ = 'whatever'

    name = Column(String, primary_key=True)
    email = Column(String)
    bio = Column(String)

    # other code

    def dict(self):
        return {'name': self.name,
                'email': self.email,
                'bio': self.bio,
               }

Then you do something like:

return [user.dict() for user in usermodel]

That may be your best solution here.

Wayne Werner
  • 49,299
  • 29
  • 200
  • 290