2
votes

There are posts on how to set, get, KeyProperty/StructuredProperty, but nothing tells me how to use NDB for modeling many-to-one.

I have two Models:

class Department(ndb.Model):
   department_id = ndb.IntegerProperty()
   name          = ndb.StringProperty()

class Student(ndb.Model):
    student_id = ndb.IntegerProperty()
    name       = ndb.StringProperty()
    dept    = ndb.KeyProperty(Kind=Department)

How is the many-to-one is ensured, i.e whenever there is an insert into student record, it has to validate department key w.r.t to department datastore?

How do you insert student record to ensure many-to-one relationship?

Option 1:

# Insert student record without checking for valid dept id. GAE automatically validates
student = Student(student_id=...., dept=ndb.Key(Department, input_dept_id))

Option 2:

# check for valid dept id and then insert student record
dept_key = ndb.Key(Department, input_dept_id)
if(dept_key.get()):
     student = Student(student_id=...., dept=dept_key)

I tried option 1 with an dept_id not in department entities and it was able to insert that student entity. I'm fairly new to GAE.

1
GAE won't "validate" your keys and will let you use any key you want even if it doesn't point to an existing entity. You need to make sure that you are using valid keys on your own. Your option 2 is one solution.gaefan
One thing to note you code has Department as a class. So Department in each Key constructor should be "Department" - Student(student_id=...., dept=ndb.Key("Department", input_dept_id))Tim Hoffman
@TimHoffman, Thank you for the input. Department without quotes seems to be working for me. It is able to fetch the entity.psun

1 Answers

1
votes

According to the documentation (https://cloud.google.com/appengine/docs/python/datastore/entities), "The Datastore API does not distinguish between creating a new entity and updating an existing one". That is, the put() method will either create a non-existing entity or update an existing one.

So, Option 2 seems the way to go. (Option 1 indeed does not provide any validation)