1

I recently switched from ext.db to the new NDB and having difficulties.

I want to convert structured list into Json package so I can send to an iPhone app. I get "not JSON serializable" error. I want to package so that all the user's favorite fruits are converted to Json. If a user likes apple, orange, and strawberry, then in the favorites field of Json (below code) should have all three fruits and associated scores and comments.

I know to_dict exist, as well as jsonProperty, but I do not know how to apply if applicable.

Following is what I have:

class FavFruits(ndb.Model):
    fruit    = ndb.StringProperty()
    score    = ndb.IntegerProperty()
    comment  = ndb.TextProperty()

 class UserProfile(ndb.Model):
    uid            = ndb.StringProperty(required=True)
    favFruits      = ndb.StructuredProperty(FavFruits, repeated=True)

 @classmethod
 def makeJsonPackage(cls, uid):
      fruitList = UserProfile.query(UserProfile.uid == uid).get()
            entry = {}
            entry["uid"]           = fruitList.uid
            entry["favorites"]     = fruitList.favFruits
            return (entry)

 # down stream of the code
 jsonData = UserProfile.makeJsonPackage(uid)
 self.response.write(json.dumps(jsonData))

This does not work.. problem is at entry["favorites"] = fruitList.favFruits as I am having problem converting structured list into Json data.

Goal: Send the entire list of favFruits entries (multiple fruits). I would like to keep structuredList as I want to query the data when the user requests, say, "apple", so that I can display the fruit (apple) and associated score and comments.

Any help will be greatly appreciated.

jbro
  • 75
  • 9

1 Answers1

2

based on AppEngine Making ndb models json serializable and document, the following code should work.

Returns a dict containing the model's property values. Property values for StructuredProperty and LocalStructuredProperty are recursively converted into dictionaries.

@classmethod
def makeJsonPackage(cls, uid):
    fruitList = UserProfile.query(UserProfile.uid == uid).get()
    return json.dumps(fruitList.to_dict())

Update1

userPorfile = UserProfile.query(UserProfile.uid == uid).get()
return json.dumps([k.to_dict() for k in userProfile.favFruits])

EXTRA: Use Endpoints

Since you want to use AppEngine as Backend api server for your mobile application. check the Endpoints API first, It is especially designed for this kind of usage.

https://developers.google.com/appengine/docs/java/endpoints/

Based on endpoints, there is a google support package called Endpoints Proto Datastore API. Which provide more directly connection for ndb Model and endpoints. It is a little hard at first, but after you know how it works, it is very powerful and can save a lot of time.

http://endpoints-proto-datastore.appspot.com/

Update 2:

EDIT1: I wrote a RESTFul api generator for ndb Model.

# generate restful api in one line
BigDataLab = EndpointRestBuilder(GPCode).build(
    api_name="BigDataLab",
    name="bigdatalab",
    version="v1",
    description="My Little Api"
)

repo: https://github.com/Tagtoo/endpoints-proto-datastore-rest

Community
  • 1
  • 1
lucemia
  • 6,349
  • 5
  • 42
  • 75
  • Thank you for your input. I tried the suggested change, but I am still having issues as I get _AttributeError: 'list' object has no attribute 'to_dict'_ My actual database has other columns like `loginDateTime` which I don't want to put in JSON pack. Is it possible to do this? What I need to convert to dict is `favFruits` entries only, and not `uid`, or am I missing something? Also, thank you for Endpoints suggestion; I will definitely look into this for production site. – jbro Apr 06 '14 at 17:42