[storm] How to JSON encode a item from a ResultSet

Jamu Kakar jkakar at kakar.ca
Thu May 27 21:33:54 BST 2010


Hi Mario,

On Thu, May 27, 2010 at 10:14 PM, Mario Zito <mazito at analyte.com> wrote:
> I would like to iterate over all items of a returned ResultSet encoding each
> one using JSON. Example code follows:
> class Topic(object):
>     __storm_table__= "Trancos.topic"
>     id = Int(primary=True)
>     account_id= Int()
>     title= Unicode()
>     properties= Unicode()
>     notes= Unicode()
>     # and other attrs not important here ...

8< snip

>     rs= store.find(Topic)
>     for t in rs:
>         print t.id, json.dumps(t)
> But I get the error:
>   File "/usr/lib/python2.6/json/encoder.py", line 344, in default
>     raise TypeError(repr(o) + " is not JSON serializable")
> TypeError: <__main__.Topic object at 0x26f3090> is not JSON serializable
>
> Any ideas ? Is there a way to serialize a Storm object (or a full ResultSet)
> to JSON ?

You need to create a custom encoder for use with simplejson.  One
way forward is to create a custom encoder for each of your Storm
objects.  See the 'Specializing JSON object encoding' section in the
simplejson documentation for more information [1].  Something like
this should work (untested):

  import simplejson

  def encode_topic(topic):
      if isinstance(topic, Topic):
          return {"id": topic.id, "account_id": topic.account_id,
                  "title": topic.title, "properties": topic.properties,
                  "notes": topic.notes}
      raise TypeError(repr(topic) + " is not JSON serializable")

  print simplejson.dumps(topic, default=encode_complex)

This will get tedious if you have many different kinds of objects to
convert, so you might want to create a generic encoder function that
will work with any Storm object, for example (also untested):

  import simplejson as json
  from storm.info import get_cls_info

  def encode_storm_object(object):
      if not hassattr(object, "__storm_table"):
          raise TypeError(repr(object) + " is not JSON serializable")

      result = {}
      cls_info = get_cls_info(object.__class__)
      for name in cls_info.attributes.iterkeys():
          result[name] = getattr(object, name)
      return result

  storm_object = get_storm_object()
  print simplejson.dumps(storm_object, default=encode_storm_object)

This won't dump non-Storm fields though, which may or may not be a
problem depending on your needs.  Hopefully it's enough to get you
started doing what you want.

Thanks,
J.

[1] http://simplejson.googlecode.com/svn/tags/simplejson-2.1.1/docs/index.html



More information about the storm mailing list