Understanding the ndb Key Class and KeyProperty

I looked through the documentation, documents and answers to questions and answers, and I'm still struggling with understanding a small part of this. What to choose and when?

This is what I read so far (just a sample):

The key class seems pretty simple to me. When you create an ndb object, the data warehouse automatically creates a key for you, usually in the form of a key (Kind, id), where an identifier is created for you.

Let's say you have these two models:

class Blah(ndb.Model): last_name = ndb.StringProperty() class Blah2(ndb.Model): first_name = ndb.StringProperty() blahkey = ndb.KeyProperty() 

So, just using the key, and you want to make Blah1 a parent (or have several family members with the same name)

 lname = Blah(last_name = "Bonaparte") l_key = lname.put() **OR** l_key = lname.key.id() # spits out some long id fname_key = l_key **OR** fname_key = ndb.Key('Blah', lname.last_name) # which is more readable.. 

then

 lname = Blah2( parent=fname_key, first_name = "Napoleon") lname.put() lname2 = Blah2( parent=fname_key, first_name = "Lucien") lname2.put() 

So far so good (I think). Now about KeyProperty for Blah2. Suppose Blah1 is still the same.

 lname3 = Blah2( first_name = "Louis", blahkey = fname_key) lname3.put() 

Is it correct?

How to request various things

Request Name:

 Blah.query() # all last names Blah.query(last_name='Bonaparte') # That specific entity. 

Name:

 Blah2.query() napol = Blah2.query(first_name = "Napoleon") bonakey = napol.key.parent().get() # returns Bonaparte key ?? bona = bonakey.get() # I think this might be redundant 

that's where i get lost. How to search for Bonaparte from the first name using a key or key property. I did not add it here and may have had it, and this is a discussion of parents, great parents, great parents, since Case keeps track of ancestors / parents.

How and why you will use KeyProperty against the inherent key class. Also imagine that you have 3 sensors s1, s2, s3. Each sensor had thousands of readings, but you want to keep the readings associated with s1 so that you can graphically read all the readings for today for s1. What would you use? KeyProperty or a key class? We apologize if this was answered elsewhere, but I have not seen a clear example / guide on choosing what and why / how.

+4
source share
2 answers

I think the confusion comes from using a key. The key is not associated with any properties within the object; it is the only unique identifier for finding a single object. It can be either a number or a string.

Fortunately, all of your code looks good, except for one line:

 fname_key = ndb.Key('Blah', lname.last_name) # which is more readable.. 

Building a key takes a unique identifier that does not match the property. That is, it will not bind the variable lname.last_name to the last_name property. Instead, you can create your entry as follows:

 lname = Blah(id = "Bonaparte") lname.put() lname_key = ndb.Key('Blah', "Bonaparte") 

You have only one Blah object with this ID. In fact, if you use a string like last_name as an identifier, you do not need to store it as a separate property. Imagine that an object identifier is a unique unique string property.

Further. Be careful to assume that Blah.last_name and Blah2.first_name are unique in your queries:

 lname = Blah2( parent=fname_key, first_name = "Napoleon") lname.put() 

If you do this more than once, there will be several objects with the first name Napoleon (all with the same parent key).

Continuing your code above:

 napol = Blah2.query(first_name = "Napoleon") bonakey = napol.key.parent().get() # returns Bonaparte key ?? bona = bonakey.get() # I think this might be redundant 

napol contains the query, not the result. You need to call napol.fetch() to get all objects with "Napolean" (or napol.get() if you are sure that there is only one entity). bonakey is the opposite; it contains the parent because of the get () key, not Bonaparte. If you left the .get () function, then bona will correctly have a parent element.

Finally, your question about sensors. You may not need KeyProperty keys or "integral" keys. If you have a reading class as follows:

 class Readings(ndb.Model): sensor = ndb.StringProperty() reading = ndb.IntegerProperty() 

then you can save them all in one table without keys. (You might want to include a timestamp or other attribute.) You may later receive the following request:

 s1_readings = Readings.query(Readings.sensor == 'S1').fetch() 
+2
source

I am also new to NDB, and so far I still do not understand, but I think that when you create Blah2 with a parent for Napoleon, you will need a parent request or not. For instance:

 napol = Blah2.query(first_name = "Napoleon") 

It won’t get anything (and you don’t use the right format for NDB), but using the parent will do:

 napol = Blah2.query(ancestor=fname_key).filter(Blah2.first_name == "Napoleon").get 

I don't know if this adds light to your question.

+1
source

All Articles