Hi Ben,

You have two options here, either of which would appear to suit your
situation very well:

1) Use App Engine's built in support for parent entities and entity groups.
When creating a node, pass the parent= argument to the constructor, passing
the key or model instance of the parent node. All entities with the same
root node can be updated atomically in a single transaction. To fetch all
the entities of a tree, do MyEntity.all().ancestor(rootkey).
2) Encode your entire tree in a single entity - for example, by pickling it.

Which of the two is better depends on a few external factors - for example,
do you ever need to look up individual tree nodes by criteria other than
their membership in a particular tree?

-Nick Johnson

On Sat, Jun 6, 2009 at 4:41 PM, Ben FS <ben.su...@gmail.com> wrote:

>
> Hi Nick,
> I'm faced with a similar question as the original poster and can
> provide additional details on the nature of the tree and operations in
> my case, as you request below. I'm hoping this will make it possible
> for you to help me out.
>
> Yes, I would like tree modifications to be wrapped in transactions.
> Assuming "1QPS of updates" means "one datastore write per second", the
> answer is yes, I expect write frequency for a single tree to be within
> that limit.
> My trees will be shallow (typically 1-4 levels deep; user-defined and
> if needed I can enforce a limit).
> The number of nodes in a tree will typically be <30 and rarely if ever
> >100.
> Occasionally an update will need to modify attribute values on
> multiple nodes within a branch, and should occur within a transaction.
> A given request (via AJAX) will typically read the entire tree
> structure (of a single tree). There will be far more reads than
> writes, and it is okay for writes to be less snappy, but I'd like
> reads of the entire tree to be fast.
>
> Operations:
> 1. Read the tree of entities: Get the whole tree. List all root nodes.
> Given any node, retrieve its children. Given any node, retrieve the
> entire sub-tree. Given any node, retrieve its parent. Query all nodes
> based on some attributes.
> 2. Write a tree of entities: Add a root node. Add a child node. Remove
> a node. Removing a node that has children should have two options: a)
> fail, or b) cascade (remove all generations of children). Modify
> attributes on a single node. Modify attributes of a set of nodes
> (usually within a branch, e.g. update ancestors bottom-up).
>
> I'm currently using the Java runtime with low-level datastore API, but
> also use Python, and am interested in this from a general point of
> view.
>
> A little more info, not sure if this helps:
> My app has multiple projects with multiple project members each.
> Within each project there are two main tree structures, G and O, each
> with variable number of levels, and multiple nodes at the root level
> (users see G and O as lists initially and then each item is broken
> down further, developing a tree). Each node (in both G and O) has
> various attributes, some of which have numerical values. Numerical
> attributes of leaf nodes are modified by users; numerical attributes
> of non-leaf nodes are computed from those of their children. In
> addition the two trees are interrelated: each leaf node of G is linked
> to each leaf node of O. For each such pairing additional attributes
> exist and their values can be modified by users.
>
> Alternatively, you can think of two lists of items, cross-related to
> form an MxN matrix, with these items forming the leaves of two tree
> structures (G and O) superimposed on the lists (M leaves of G and N
> leaves of O).
>
> I appreciate any advice you can provide!
>
> Thanks,
> Ben.
>
> On Apr 28, 4:22 am, Nick Johnson <nick.john...@google.com> wrote:
> > The best way to do this depends on the nature of thetree, and what
> > sort of operations you need to do on it.
> >
> > If you need transaction support and will do less than about 1QPS of
> > updates to the entiretree, you could use the datastore's built in
> > Ancestor model - construct entities with the 'parent' argument to the
> > constructor. This also means you can't change the parent of an
> > existing entity.
> >
> > If the above isn't satisfactory, but your trees will be relatively
> > shallow (say, typically less than 100 levels deep), you can store an
> > ancestor list in a ListProperty. This way, you can select all
> > descendents of a given node easily.
> >
> > Other options are available, of course, but they entail multiple
> > operations to retrieve a whole subtree. If you give more detail as to
> > what you're representing and your access patterns, I can suggest more
> > alternatives.
> >
> > -Nick Johnson
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to google-appengine@googlegroups.com
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to