Will Curran
Will Curran

Reputation: 7110

Simplejson dump and load not returning valid dictionary

I'm trying to store a json result in the GAE datastore, so that I can read it later. I'm dumping it to a String, then storing it, then reading it and loading it back into a dict. But I can no longer read it as a dict after loading.

result = freebase.mqlready(query)

Print result:

[{u'mid': u'/m/095hd',
  u'name': u'Settlers of Catan',
  u'type': u'/games/game'},
 {u'mid': u'/m/025sm93',
  u'name': u'The Game of Life',
  u'type': u'/games/game'}]

 

for r in result:
    name = r.name # works, I can get the name and other values.

json_dump = simplejson.dumps(result)
text = db.Text(json_dump)
fbresult = model.FB(text=text)
fbresult.put()
####
stored_text = fbresult.text
json = simplejson.loads(stored_text)

Print json:

[{u'mid': u'/m/095hd',
  u'name': u'Settlers of Catan',
  u'type': u'/games/game'},
 {u'mid': u'/m/025sm93',
  u'name': u'The Game of Life',
  u'type': u'/games/game'}]

 

for j in json:
    name = json.name 

ERROR:

AttributeError: 'dict' object has no attribute 'name'

Upvotes: 2

Views: 2851

Answers (3)

jfs
jfs

Reputation: 414215

Ordinary dictionary doesn't transform attribute access into item lookup:

>>> d = {'name': 'Joe'}
>>> d.name
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'name'
>>> d['name']
'Joe'

simplejson returns ordinary dictionaries by default.

You could use Storage object that is like a dictionary except obj.foo can be used in addition to obj['foo'].

>>> from storage import Storage
>>> s = Storage(d)
>>> s['name']
'Joe'
>>> s.name
'Joe'

You could convert all json-objects to Storage using object_hook parameter:

obj = simplejson.loads(stored_text, object_hook=Storage)

Upvotes: 2

Tyler Eaves
Tyler Eaves

Reputation: 13121

Uh, looks like you're accessing the collection rather than the inner object:

Surely you meant:

for j in json:
    name = j['name']

Upvotes: 9

albertov
albertov

Reputation: 2348

It seems that the result returned by freebase.mqlready is not a real dict but a subclass which delegates to __getitem__ via __getattr__ (ie: you can do r.name instead of r['name']). simplejson can dump it just fine (it is a dict subclass) but when it loads it back it returns a plain dict instead which doesn't delegate attribute access to item access.

Upvotes: 1

Related Questions