key_name length limits?

9 views
Skip to first unread message

Andy Freeman

unread,
Oct 15, 2008, 5:03:27 PM10/15/08
to Google App Engine
I'd like to construct a key_name (for get_or_insert) by concatenating
the name() s of a couple of db.Key s.

Marzia Niccolai

unread,
Oct 15, 2008, 5:19:07 PM10/15/08
to google-a...@googlegroups.com
Hi Andy,

I believe there is a limit on key names of 500 bytes, but I can't seem to find it in the documentation.

I think the question I have is there a reason you are not using entity groups?  When using entity groups you can use Key.from_path() to construct key objects from the ancestor path:
http://code.google.com/appengine/docs/datastore/keyclass.html#Key_from_path

This way you don't need to build up longer and longer key names.

-Marzia

Andy Freeman

unread,
Oct 16, 2008, 12:12:51 AM10/16/08
to Google App Engine
I'm not using entity groups (in this case) because the entity/db.Model
instance that I'm constructing doesn't have a reasonable ancestor.
There will be too many of them to put under any of the db.Model
instances that I'm using to build the key_name, let alone to put under
a single root.

The db.Model instance that I'm creating will not be used to create
other keys. The other db.Model instances whose Keys() I want to use
to create the key_name are likewise either root entities or at a very
short depth in an entity dag.

I'd assumed that the length of a db.Model instance's db.Key().name()
was a constant plus a linear function of the depth the entity in its
entity group.

If my assumption is true, the key_names that I'm planning to construct
will have bounded length. If the db.Key() s constructed by the dev
environment are the same length as those in the production
environment, I should be able to figure out whether said bounded
length is less than the max length of a key_name.


On Oct 15, 2:19 pm, "Marzia Niccolai" <ma...@google.com> wrote:
> Hi Andy,
>
> I believe there is a limit on key names of 500 bytes, but I can't seem to
> find it in the documentation.
>
> I think the question I have is there a reason you are not using entity
> groups?  When using entity groups you can use Key.from_path() to construct
> key objects from the ancestor path:http://code.google.com/appengine/docs/datastore/keyclass.html#Key_fro...
>
> This way you don't need to build up longer and longer key names.
>
> -Marzia
>
>
>
> On Wed, Oct 15, 2008 at 2:03 PM, Andy Freeman <ana...@earthlink.net> wrote:
>
> > I'd like to construct a key_name (for get_or_insert) by concatenating
> > the name() s of a couple of db.Key s.- Hide quoted text -
>
> - Show quoted text -

Ross Ridge

unread,
Oct 16, 2008, 5:13:09 AM10/16/08
to Google App Engine
Andy Freeman wrote:
> I'd assumed that the length of a db.Model instance's db.Key().name()
> was a constant plus a linear function of the depth the entity in its
> entity group.

The length of the instance's db.Key().name() is the same as the
key_name you set when you created it. If you didn't set a key_name
then the entity has an id whose length I don't think is dependent on
its depth in its entity group. The id (and key_name) is only unique
amongst the enities with both the same kind and parent, so there's no
need for it to be any longer because it's depth.

Ross Ridge

Andy Freeman

unread,
Oct 16, 2008, 12:07:34 PM10/16/08
to Google App Engine
If the lenghth of an instance's db.Key().name() when key_name isn't
set is a constant, that's even better for my purposes.

Marzia Niccolai

unread,
Oct 16, 2008, 12:10:51 PM10/16/08
to google-a...@googlegroups.com
If key_name isn't set, db.Key().name() will return None.

-Marzia

Andy Freeman

unread,
Oct 16, 2008, 2:59:56 PM10/16/08
to Google App Engine
Right - I wrote db.Key().name() for input to construct a key_name when
I should have written str of db.Key instance.

In short, I have three root db.Model instances that were constructed
without a key_name, I want to construct a key_name for another root
instance by concatenating str of those instance's key() s.

I'm doing this because if str(x.key()) is unique, concatenating them
will also be unique.
> > >                                         Ross Ridge- Hide quoted text -

Andy Freeman

unread,
Oct 16, 2008, 4:36:39 PM10/16/08
to Google App Engine
> I'd assumed that the length of a db.Model instance's db.Key().name()
> was a constant plus a linear function of the depth the entity in its
> entity group.]

As I wrote above, I should have said length of str(db.Key() instance).

db.Key's __str__ definition on google/appengine/api/
datastore_types.py, line 404 says

Unfortunately, this string encoding isn't particularly compact,
and its
length varies with the length of the path. If you want a shorter
identifier
and you know the kind and parent (if any) ahead of time, consider
using just
the entity's id or name.
> > - Show quoted text -- Hide quoted text -

Ross Ridge

unread,
Oct 17, 2008, 8:14:55 AM10/17/08
to Google App Engine
Andy Freeman wrote:
> > I'd assumed that the length of a db.Model instance's db.Key().name()
> > was a constant plus a linear function of the depth the entity in its
> > entity group.]
>
> As I wrote above, I should have said length of str(db.Key() instance).
>
> db.Key's __str__ definition on google/appengine/api/
> datastore_types.py, line 404 says
>
> Unfortunately, this string encoding isn't particularly compact,
> and its
> length varies with the length of the path. If you want a shorter
> identifier
> and you know the kind and parent (if any) ahead of time, consider
> using just
> the entity's id or name.

The string contains all the elements of key's path encoded for use in
a URL, so length of generated string will be proportional to the sum
of the length of all the components. The only unknown here is the
length ids that the production server generates, but unless Google is
using something GUIDs they shouldn't be too long.

As the comment suggests you can get a more compact string by
generating it yourself. If all your kinds are the same you could use
something like:

def id_path_string(entity):
parent = entity.parent()
if parent == None:
return hex(entity.key.id())
return id_path_string(parent) + ":" + hex(entity.key.id())

Ross Ridge

Andy Freeman

unread,
Oct 17, 2008, 1:53:16 PM10/17/08
to Google App Engine
Thanks.

I use a variety of db.Models and wanted some more error checking so I
wrote something a bit more general but it's basically the same idea.
(Since root instances can have key names instead of ids, I use
whatever is there. I include the model names and enough structure so
I can see what the input instances were and could even parse it to
db.Key.from_path() them if necessary.)

I also compare what I generate to the length of the str of the key and
use whatever is shorter.
>                                         Ross Ridge- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages