I have started working on an existing project which uses Google Datastore where for some of the entity kinds every entity is assigned the same ancestor. Example:
<
This was probably done to achieve strongly consistent queries within the group. As you've pointed out this design has... drawbacks.
If this is solely reference data (i.e. Read many write once) that may mitigate some of the negatives, but also mostly invalidates the positives (i.e. Eventual consistency is not a problem if data doesn't update often).
Grouping many entities inside a single entity group offers at least 2 advantages I can think of:
The 1 write/second/group limit might not be a scalability issue at all for some applications (think write once read a lot kind of apps, for example, or apps for which 1 write per sec is more than enough).
As for the mechanics, the (unique) parent "entity" key for the group is the ndb.Key('Group', "xxx_group")
key (which has the "xxx_group" key ID). The corresponding "entity" or its model doesn't need to exist (unless the entity itself needs to be created, bu that doesn't appear to be the case). The parent key is used simply to establish the group's "namespace" in the datastore, if you want.
You can see a somehow similar use in the examples from the Entity Keys documentation, check out the Message
use (except Message
is just a "parent" entity in the ancestor path, but not the root entity):
class Revision(ndb.Model): message_text = ndb.StringProperty()
ndb.Key('Account', 'sandy@foo.com', 'Message', 123, 'Revision', '1') ndb.Key('Account', 'sandy@foo.com', 'Message', 123, 'Revision', '2') ndb.Key('Account', 'larry@foo.com', 'Message', 456, 'Revision', '1') ndb.Key('Account', 'larry@foo.com', 'Message', 789, 'Revision', '2')
...
Notice that Message is not a model class. This is because we are using Message purely as a way to group Revisions, not to store data.