colin_dev256 colin_dev256 - 1 month ago 17
Python Question

GAE posting an array to the datastore with Python (One to Many)

Been workining with GAE for a few months. It's my first time working with One-to-Many relationships here. Everything has been posting all well to the datastore until I started with relationships. This is the first one. Could someone please help me with this 'post' to datastore? The docs and other examples are quite confusing for now. I know I'm doing it incorrectly by

employees=r['Employees'],
I just want a simple post first. If you could plunker it even better! I am getting a BadValueError upon posting as shown;

enter image description here

model.py

class Project(ndb.Model):
projectID = ndb.IntegerProperty(required=True)
title = ndb.StringProperty(required=True)
description = ndb.StringProperty(required=True)
startAt = ndb.DateTimeProperty(indexed=True)
endAt = ndb.DateTimeProperty()
employees = ndb.KeyProperty(kind='Employees', repeated=True)

class Employees(ndb.Model):
name = ndb.StringProperty()
role = ndb.StringProperty()


handlers.py

def post(self):
r = json.loads(self.request.body)
print str(r)

g = Project(projectID=int(r['ProjectID']),
description=r['Description'],
title=r['Title'],
employees=r['Employees'],
startAt=datetime.strptime(r['StartAt'], '%d/%m/%Y %H:%M %p'),
endAt=datetime.strptime(r['EndAt'], '%d/%m/%Y %H:%M %p'))

project_key = g.put()
project_key.get()
print project_key


controller.js

$scope.employees = [
{
name:'mark',
role: 'dev'
},
{
name:'colin',
role: 'dev2'
},
];


UPDATE----------------------------------------------------------------------

json handler

class commentsJsonHandler(webapp2.RequestHandler):
@classmethod
def route(cls):
"""
name: index, template: /
"""
return webapp2.Route('/comments', handler=cls, name='_commments_')


def get(self):
recommendations = Project.query()

def date_handler(obj):
if isinstance(obj, datetime):
return obj.isoformat()
else:
raise TypeError

self.response.out.write(json.dumps([dict(rec.to_dict(), **dict(id=rec.key.id())) for rec in recommendations], default=date_handler))

Answer

You have to iterate over the employees collection in your json payload and create those Employee entities first and use their keys to create the Project entity

def post(self):
    r = json.loads(self.request.body)
    print str(r)
    employee_keys = []
    for emp in r['Employees']:
        employee = Employees(name=emp['name'], role=emp['role'])
        employee.put()
        employee_keys.append(employee.key)


    g = Project(projectID=int(r['ProjectID']),
                description=r['Description'],
                title=r['Title'],
                employees=employee_keys,
                startAt=datetime.strptime(r['StartAt'], '%d/%m/%Y %H:%M %p'),
                endAt=datetime.strptime(r['EndAt'], '%d/%m/%Y %H:%M %p'))

    project_key = g.put()
    project_key.get()
    print project_key