Can anyone tell or define more what is "ancestor" and give an example on it and also what it is for? I just can't grasp what it really is.
Reference: http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query_ancestor
Thanks.
Transactions in GAE only exist within ancestor-descendant groups. Equivalently, quoting the docs at the URL I just gave,
All datastore operations in a
transaction must operate on entities
in the same entity group
and an "entity group", per this page in the docs, are defined by:
When the application creates an
entity, it can assign another entity
as the parent of the new entity, using
the parent argument in the Model
constructor. Assigning a parent to a
new entity puts the new entity in the
same entity group as the parent
entity.
"Ancestor" is just the transitive closure of "parent" -- i.e., given an entity, its ancestors are, its parent, its parent's parent, and so forth.
Related
Sometimes, you make an entity kind that is supposed to exist in another entity. However, if it turns into an orphan, it will have no reason to exist in the datastore anymore.
What happens to child datastore objects after deleting the ancestor?
According to the link above,
"Child entities do not get deleted when the ancestor is deleted"
"child_entity.key.parent().get() will return None."
If I delete the ancestor, the child will have no parent, making it an orphan.
This is a problem, as there is no reason for it to stay in the datastore anymore.
Is there any way to ensure this never happens in the database?
Possible solutions I can think of are:
Routinely run macros to delete orphans
Try to clean the code/weed out bugs that may cause my child to turn into an orphan
However, the I'm hoping for a more programmatically correct solution like an attribute or property that can be set to ensure me that the parent(key) will never point an entity that doesn't exist. (aka automatically delete the entity when ancestors are deleted)
Is there?
If yes, what is it?
If no, why not?
A child entity can never become a root entity, since it continues to have the same parent key, even if the parent was deleted (or never existed).
An entity's parent key can not be changed during the entity's lifetime since the parent key is embedded in the entity's key.
As for automatically removing an entity's descendents when the entity is deleted - there is no such way. But it can be achieved programatically, see How to delete an entity including all children.
I want to understand the parent/child (ancestor paths) relationship found in the Google AppEngine datastore that wasn't mentioned in the online documentation. What happens to children objects when the parent is deleted? Do child objects also get deleted? Do they become orphaned without a parent? If so how would you query for them?
Google Help Doc regarding Ancestor Paths: https://cloud.google.com/appengine/docs/go/datastore/entities#Go_Ancestor_paths
Thanks!
~Todd
Child entities do not get deleted when the ancestor is deleted: there's no 'cascade on delete' behaviour. In fact, an ancestor entity doesn't even have to exist when defining an entity group (only its Key).
They will remain unaffected, you will just be unable to get their parent entity. i.e.
child_entity.key.parent().get()
will return None.
I am currently learning more about the Google App Engine datastore, and I have some doubts regarding my understanding of the concept of defining a parent key. Now, here's the code for defining a parent key from the GAE documentation:
def guestbook_key(guestbook_name="default"):
"""Constructs a Datastore key for a Guestbook entity with guestbook_name."""
return ndb.Key('Guestbook', guestbook_name)
Note: this code is included in the source code of an application which accepts entries from a user and stores it in a datastore and displays them collectively on the homepage.
Now, this is what I understand from this code(please correct me if my understanding of this concept is not what it is supposed to be):
The 'guestbook_key' function defines a parent key, which we have named as 'default', for all the posts that the user submits into the datastore. So basically, all the posts that are submitted by the user are stored in an entity named 'Guestbook', and we define a key for it's parent(which is non-existent) named 'default'.
Please correct me wherever I went wrong with my understanding.
It really depends on how you use this key. Right now, it is just a name. If you put() it, you are putting a Guestbook type with the name "default".
However, if you are using it as a parent, then you may have code that looks like this:
post = Post(parent=guestbook_key())
post.comment = "This is a new post!"
post.put()
In this case, the new Post object will have the Guestbook object with the name "default" as a parent. Then, you could use an ancestor query to get all Posts for a given guestbook.
The reason you might choose to do this (rather than, for example, have a property on each post with the name of the guestbook) is that it guarantees strongly consistent results. This basically allows all requests to see a consistent view of a guestbook. If you didn't have strongly consistent results, you may see cases where a user writes a post but when they look at the guestbook it doesn't appear.
You are correct that you never actually need to create the Guestbook entity. When you define a parent key, it is actually creating a key where the parent key is a prefix of the child key.
I'm hoping someone's seen this. I've found no clues on Google.
I'm using Google AppEngine with JDO to persist my objects.
I have two objects, Parent and Child. Each Parent has n Child objects.
I initially stored the Child objects in an ArrayList data member in the Parent class.
I got the exception "java.lang.UnsupportedOperationException: FK Arrays not supported" when persisting the Parent object.
I put this down to my storing more than one Child key references, so changed it around so that the Child objects store key references to the Parent object instead. In this way, there is only one key reference per Child object instead of n key references per Parent object.
Yet the exception still gets thrown when persisting the Parent object. So I suspect I was mistaken about the probable cause of this exception.
Has anyone seen this exception or know what it means?
According to DataNucleus a lot of things are persisted by default... and they even had a complaint in their blog about the manual in the google app engine site, which said that you need to explicitly mark fields as #Persistent.
I figured out what was wrong.
It wasn't complaining about my ArrayList.
My Parent class had an array data member that I hadn't put an annotation on. Arrays are persisted by default in the absence of annotations.
I added the annotation #NotPersistent and this solved my problem.
When I update an entity, the entity needs to change parent, is there any way to do that?
The clean way, and generally the only applicable one, is to make a new entity with the new parent and everything else copied, and delete the old one. Parents become part of an entity's key, so it's definitely NOT trivial to "change" that except by this kind of approach!