> i'm curious how a named key buys you anything here beyond what an id-
> based key gives you.

With named keys, it's trivial to create all of the entities in a given
group with a single put, which is a transaction.  With id-based keys,
multiple puts are required.  In a case that I care about (see below),
I can't bundle those puts into a single user-defined transaction.

Which reminds me - is the transaction for db.put([a, b,]) (for a and b
in the same entity group) run in the datastore or is it run using an
application-side transaction like

def put_a_b_in_transaction():
    a.put()
    b.put()

db.run_in_transaction(put_a_b_in_transaction)

If db.put([a, b,]) is run in the datastore, are there any interesting
differences from the application-side transaction version?  (I'd
expect that the application-side transaction requires some back and
forth with the datastore which offers some opportunities for the
transaction to be aborted for quota reasons.)

> def create():
>   parent = Foo()
>   parent.put()
>   child = Foo(parent=parent)
>   child.put()
>   return parent
>
> parent = run_in_transaction(create)
>
> i'm still curious, so i'm probably missing something...?

You're missing the ability to read my mind.  I haven't mentioned that
(my) parent has references to (some of) its children.

The "one put per entity in a transaction" rule means that I can't
update parent in that transaction after the child put.  I can't use
parent as a parent until it has a valid key.  I can't generate a
child's key until I can get a valid key for its parent.  Since I want
parent to have (some) child keys and I can't update it (in the same
transaction) after I put it, I need to be able to generate all keys
before any puts.

Yes, I could add the parent's key to the relevant children and use
parent.child_set (the collection back-link) to get to those children,
but that's a query and even if it's as efficient as db.get, a parent
entity that doesn't have a child's key can't ask memcache for said
children memcache'd by their key.

Yes, I could memcache a parent's child keys, but we're starting to
pile hack upon hack.

Since globally unique keys have other uses, I'd rather use them here
as well and make things easy.

FWIW, caring (too much) about how named entities work is how I found
issue 883

http://code.google.com/p/googleappengine/issues/detail?id=883&can=4&colspec=ID%20Type%20Status%20Priority%20Stars%20Owner%20Summary%20Log%20Component
.

On Dec 11, 2:40 pm, ryan <ryanb+appeng...@google.com> wrote:
> hi all! there's lots of good information in this thread on how to
> generate partially and fully unique ids, along with pros and cons. i'm
> also curious about the actual use case, though. specifically...
>
> On Nov 22, 6:38 pm, Andy Freeman <ana...@earthlink.net> wrote:
>
>
>
> > Each db.put has significant overhead.  If I can generate a unique name
> > without a db.put, I can reduce the number of db.puts that my
> > application does by a factor of 2.
> ...
> > It introduces a clean-up problem.   I can't delete such an object
> > until after I delete all entity groups named using said object's key.
> > (GAE is free to reused generated keys.)
>
> > I shouldn't have mentioned the overhead of puts.  The real problem is
> > cleanup and consistency, a problem that transactions are designed to
> > solve.
>
> i'm curious how a named key buys you anything here beyond what an id-
> based key gives you.
>
> as background, from my perspective, named keys are useful when you
> have an external identifier and you want to enforce and exploit
> uniqueness in a namespace that you control. they also let you do a
> limited form of querying inside transactions, via get() with a key
> that you construct in memory. we found this useful enough that we
> added get_by_key_name() as syntactic sugar for it.
>
> i suspect most of the use cases for named keys fit into that mold. as
> you mentioned, they don't generally help with optimization, since for
> a given use case, named keys will require the same number of put()s as
> id-based keys. i'm also not sure how they help with cleanup/garbage
> collection or consistency. queries and transactions don't
> differentiate between root entities with named keys vs. id-based keys.
>
> btw, you probably already know this, but just in case, you can create
> a new root entity and one or more children of that entity in the same
> transaction. e.g.
>
> def create():
>   parent = Foo()
>   parent.put()
>   child = Foo(parent=parent)
>   child.put()
>   return parent
>
> parent = run_in_transaction(create)
>
> i'm still curious, so i'm probably missing something...?
--~--~---------~--~----~------------~-------~--~----~
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