How to get ReferenceProperty's key without causing a 'get'

24 views
Skip to first unread message

Rafe

unread,
Oct 2, 2008, 6:40:58 PM10/2/08
to Google App Engine
Folks,

There have been a number of people asking on the forums what the
correct way to get the key of a ReferenceProperty without causing a
whole 'get' to the datastore. This can be especially inefficient if
you need to iterate over 100 or so values from a query, when all you
need is, say, the string version of all of those objects keys.

Let's look at an example:

class Post(db.Model):
title = db.StringProperty()
text = db.StringProperty(multiline=True)

class Comment(db.Model):
text = db.StringProperty()
post = db.ReferenceProperty(Post, collection_name='comments')

Let's say you wanted to generate a list of URLs from all the
comments in your system with links to the actual posts. This would be
an inefficient way to do this:

def generate_delete_urls(post):
urls = []
for comment in post:
key = comment.post.key()
urls.append('http://myapp.appspot.com/post/%s' % key)

The problem is that each time you de-reference the 'post' property,
it will cause a call to 'get' from the Datastore for information you
don't need.

Here is the correct way to get keys for all the posts:

def generate_delete_urls(post):
urls = []
for comment in post:
key = Comment.post.get_value_for_datastore(comment)
urls.append('http://myapp.appspot.com/post/%s' % key)

Right now, some folks may be using the protected variables that get
stored on the Model instance. This is not a good way to access
objects as it could well change in the future. If this happens, your
application can break!

So, to make sure it's clear, let me break it down for you:

reference_property = Comment.post # Gets actual
db.ReferenceProperty object
key = reference_property.get_value_for_datastore(instance)


- Rafe Kaplan

yejun

unread,
Oct 2, 2008, 7:40:54 PM10/2/08
to Google App Engine
I think you shouldn't define a post field in comment at all. Simply
make post as parent of comment when storing data.

yejun

unread,
Oct 2, 2008, 8:00:20 PM10/2/08
to Google App Engine
Then you can use parent_key() method to access key directly.

Mahmoud

unread,
Oct 3, 2008, 1:37:59 PM10/3/08
to Google App Engine
Awesome. Thanks dude.

On Oct 2, 6:40 pm, Rafe <slobberch...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages