AppEngine query for None parent - google-app-engine

I'm trying to find all object which have no parent (i.e. which were created with parent=None).
Using M.all().filter("parent = ", None).fetch(100) doesn't bring any results, even though some objects certainly do have no parent.
What am I doing wrong?

There's no way to query specifically for root entities. You need to either use external information (eg, no entity of type Foo has parents), or add a property that indicates if an entity is a root entity or not.

You don't use filter() to query for an ancestor. Try instead:
M.all().ancestor(None).fetch(100)
Edit: hmm, that won't work apparently (I'd swear I had done this somewhere). So you'd need to save an extra property as a flag for root entities.

Related

Proper way to organize data models in a MEAN stack application

I am making an MEAN stack app and use Mongoose alongside Mongo. I am struggling with organizing my objects in database. All works as expected but I have a feeling that the way I am doing things is wrong, but can't seem to find any resources on the topic that could help me, thus I hope somebody with some experience can share it with me.
I use Mongoose to create several schemas, and there is one dilemma I am facing, concerning nested objects in MongoDB.
Let's say I have a model that looks like that:
ParentSchema:{
property1:String,
children:[{}]
}
So, property1 is just some string, 'children' is an array that will contain objects of type 'Child' with some other properties, but also another array (f.ex. 'grandchildren:[{]} ), this time with another type of objects (Grandchild).
Child and Grandchild have no schemas and do not exist outside of the Parent, and will most likely be unique to each instance of Parent, so two Parents would not be sharing a Child object.
In my app, I am able to use urls such as '/parent/:id1/Child/:id2/Grandchild/:id3', where 'id1' is an actual id of Parent that Mongo generates, while 'id2' is an index of Child object instance stored in Parents array. The same goes for instances of Grandchildren stored inside Child object.
I was thinking that maybe having separate schemas for all 3 objects, and just saving references to objects is the way to go, like this:
ParentSchema:{
prop1:String,
children:[{type:ObjectId, ref:'Child'}]
}
ChildSchema:{
prop1:String,
granchildren:[{type : ObjectId, ref: 'Grandchild'}]
}
GrandChildSchema:{
prop1:String,
prop2:String
}
..but was unsure, as for me it implies that Child and GrandChild instances would be shared between different parents, however it seems easier to work with.
To sum up, I would like to know is:
which approach should I choose and why: first, second or maybe some other that I do not know about yet.
If I were to choose the second approach, should I create a separate API route for each of the objects?
How would I go about creating then? My wish is for the process to look like so:
Start creating Parent -> start creating first Child -> create some Grandchildren ->
finish creating Child -> start creating second Child -> ... -> finish creating Parent.
I apologize if the question is somehow weird, I will try to clarify as best as I can if required.
I would go with the second approach for a couple of reasons:
Schemas have better readability in my opinion.
They allow for data validation which you lack in the first approach.
Please note the answer below is primarily opinion based.
For the API design:
I think its really up to you as to which paths to expose to the consumer, since you've stated Child and Grandchild do not have the right to exist without a parent - I think your routes are fine as they are.
And finally - your process for creating these entities look fine to me. I would do the same thing myself.

How to ensure that my entity will never be an orphan?

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.

Root Query Create and Delete in Relay.js

I am trying to figure out how to create and delete nodes with Relay where I don't have a parent node. It seems that NODE_DELETE/RANGE_DELETE and RANGE_ADD all require a parent node. Is there a way to perform create and delete mutations from the root query object in Relay.js?
Note: I did find example where creates can be performed with a FIELDS_CHANGE query, but they lack any documentation or reason.
You should be able to use REQUIRED_CHILDREN for this purpose. It's not currently well-documented (or even documented), and it has a somewhat confusing name (as a result, we have a task for renaming it and improving the docs). It will likely be renamed to EXTRA_FRAGMENT in the future.
Normally when you issue a mutation, we perform an intersection between the "fat query" (all the fields that could possibly change as the result of the mutation) and the "tracked query" (all the fields that your app has requested for a node so far, and which should be updated when they change) and we send this query to the server with the mutation.
So, for the use case of creating an entirely new node with no parent, you can specify an identifying field like id in the REQUIRED_CHILDREN, and then use that to, for example, navigate to a view showing the newly-created object. This answer has a very detailed example of how you would do this.
You can pass client:root as the parentID. And then your pathToConnection would be ['client:root', 'someConnection'].
(Tested with Relay Modern. Not sure if this also applies to Relay Classic, but that's officially deprecated now anyways. But this is still one of the top Google results for this issue, so answering.)
(Found in this GitHub issue)

Google AppEngine JDO Persistence FK Arrays

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.

RIA Services and Relationships in Silverlight 3

I've finally managed to get a handle on loading information using Silverlight, ADO.NET Entities, and RIA Services, but I'm still having a problem with getting the information about the relationships.
For instance, imagine a product, and that product has several categories of attributes. We'll call them ProductAreas.
The Product object has a property called ProductAreas (as a result of their relationship), but when I call:
ctx.Load(GetProductsQuery());
(Where ctx is my DomainContext), the Product objects returned have the ProductAreas property, but it contains no elements, which is a very serious problem, in my case.
So the question is: How do I get access to these relationships?
I'm not sure what your GetProductsQuery() method does, but you should be able use the .Include('ProductAreas') method in your query. If you update your question with the contents of that method I'll try to help more.
This isn't technically the way this system is supposed to work, but I wanted to expand on your answer, while at the same time giving it the credit it rightfully deserves for leading me where I needed to be.
The solutions was to, in the GetProductsQuery() method use
return this.ObjectContext.Products.Include("ProductAreas");
instead of
return this.ObjectContext.Products;
And in the metadata file, go to the Products class and, just above the ProductAreas property add [Include()], so that it looks like:
[Include()]
public EntityCollection<ProductAreas> ProductAreas;

Resources