1
votes

I would like to be able to relate an entity of one class to another entity at the moment of the creation of both entities (one entity will have the other as it's parent and the other would have a key pointing to the other entity). It seems I am unable to obtain the key of an entity prior it gets saved to the Datastore. Is there any way to achieve the above without having to save one of the entities twice?

Below is the example:

class A(ndb.Model):
    key_of_b = ndb.KeyProperty(kind='B')

class B(ndb.Model):
    pass

What I am trying to do:

a = A()
b = B(parent=a.key)
a.key_of_b = b.key

a.put()
b.put()

If the key doesn't get assigned prior to the entity being saved, is there anyway I could construct it myself? Is there any way to achieve this or would the only solution be to save one of the entities twice?

1

1 Answers

3
votes

You could do this with named keys but then you have to be sure you can name the two entities with unique keys:

# It is possible to construct a key for an entity that does not yet exist.
keyname_a = 'abc'
keyname_b = 'def'
key_a = ndb.Key(A, keyname_a)
key_b = ndb.Key(A, keyname_a, B, keyname_b)

a = A(id=keyname_a)
a.key_of_b = key_b
b = B(id=keyname_b, parent=key_a)

a.put()
b.put()

However, I would suggest thinking about why you would need the key_of_b property in the first place. If you only set A as the parent of B then you will always be able to navigate from from A to B and the other way around:

# If you have the A entity from somewhere and want to find B.
b = B.query(ancestor=entity_a.key).get()

# You have the B entity from somewhere and want to find A.
a = entity_b.key.parent().get()

This also gives you the opportunity to create one-to-many relationships between A and B.