Problem fetching db.ListProperty data

42 views
Skip to first unread message

Simon

unread,
Aug 1, 2011, 2:43:07 AM8/1/11
to google-a...@googlegroups.com
Hi,

I'm new to appengine and I'm trying to write an app in python, however I don't think that my problem is python specific.
If somebody else already asked the same question, I'm sorry for repeating it. I searched for quite a while and couldn't find anything.

My app is a message board application where each user entity has a list of all the topics (threads) the user has participated in and each topic has a list of all users that have participated, like this.

class User(db.Model):
    user_account = db.UserProperty()
    topic_keys = db.ListProperty(db.Key)
   
    @property
    def topics(self):
        if len(self.topic_keys) == 0:
            return []
        return db.get(self.topic_keys)
    ...

class Topic(db.Model):
    name = db.StringProperty(multiline=True, required=True)
    user_keys = db.ListProperty(db.Key)
   
    @property
    def users(self):
        if len(self.user_keys) == 0:
            return []
        return db.get(self.user_keys)

In the get method of a request handler I tried to retrieve the list of users that have participated in the topic

topic_list = Topic.all().filter("name =",topic_id).fetch(limit=1)
if len(topic_list) > 0:
    topic = topic_list[0]
    topic_users = topic.users
...

But doing this gives me a Topic instance where the 'name' property is correct but topic.users is empty. However if I try to fetch the topic like below, the topic.users I get isn't empty

for tpc in pmwuser.topics:
    if tpc.name == topic_id:
        topic = tpc
        topic_users = tpc.users

What am I doing wrong in the first case? Am I modelling this wrong all together? Any help would be appreciated.

Thanks in advance

Simon

Johan Euphrosine

unread,
Aug 2, 2011, 10:58:11 AM8/2/11
to google-a...@googlegroups.com
Hi Simon,

A wild guess would be that your are not looking at the same entities
in both methods, try to check the entity key using topic.key()

You might also want to check that article about Modeling your data on
App Engine:
http://code.google.com/appengine/articles/modeling.html

Hope that helps.

> --
> You received this message because you are subscribed to the Google Groups
> "Google App Engine" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-appengine/-/BxbGdTqS6pcJ.
> To post to this group, send email to google-a...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-appengi...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-appengine?hl=en.
>

--
Johan Euphrosine (proppy)
Developer Programs Engineer
Google Developer Relations

Robert Kluin

unread,
Aug 3, 2011, 12:51:44 AM8/3/11
to google-a...@googlegroups.com
On Mon, Aug 1, 2011 at 02:43, Simon <simon.p...@gmail.com> wrote:
> Hi,
>
> I'm new to appengine and I'm trying to write an app in python, however I
> don't think that my problem is python specific.
> If somebody else already asked the same question, I'm sorry for repeating
> it. I searched for quite a while and couldn't find anything.
>
> My app is a message board application where each user entity has a list of
> all the topics (threads) the user has participated in and each topic has a
> list of all users that have participated, like this.
>
> class User(db.Model):
>     user_account = db.UserProperty()
>     topic_keys = db.ListProperty(db.Key)
>
>     @property
>     def topics(self):
>         if len(self.topic_keys) == 0:
>             return []
>         return db.get(self.topic_keys)
>     ...

Personally, I would probably write this as:
        if not self.topic_keys:
            return []
        return db.get(self.topic_keys)

I would also probably rather not make it a property, but a method
named something like get_topics. That way it is explicit that you'll
be making an RPC. Just a personal preference. ;)


>
> class Topic(db.Model):
>     name = db.StringProperty(multiline=True, required=True)
>     user_keys = db.ListProperty(db.Key)
>
>     @property
>     def users(self):
>         if len(self.user_keys) == 0:
>             return []
>         return db.get(self.user_keys)
>
> In the get method of a request handler I tried to retrieve the list of users
> that have participated in the topic
>
> topic_list = Topic.all().filter("name =",topic_id).fetch(limit=1)

See Query.get:
http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query_get

> if len(topic_list) > 0:
>     topic = topic_list[0]
>     topic_users = topic.users
> ...

After you've rewritten this using Query.get you'll have something like:

topic = Topic.all().filter("name =", topic_id).get()
if topic:
topic_users = topic.get_users()
logging.debug(topic.user_keys)


What happens if you add that logging call? Are you getting keys?


Robert

>
> But doing this gives me a Topic instance where the 'name' property is
> correct but topic.users is empty. However if I try to fetch the topic like
> below, the topic.users I get isn't empty
>
> for tpc in pmwuser.topics:
>     if tpc.name == topic_id:
>         topic = tpc
>         topic_users = tpc.users
>
> What am I doing wrong in the first case? Am I modelling this wrong all
> together? Any help would be appreciated.
>
> Thanks in advance
>
> Simon
>

Simon

unread,
Aug 18, 2011, 4:03:28 PM8/18/11
to google-a...@googlegroups.com
Thank you both for your replys. They were both very helpful to me.

I sorterd out the querying problem and I now use the following instead of having one ListProperty in User and one in Topic

class UserInTopic(db.Model):
user = db.ReferenceProperty(PMWUser, required=True, collection_name='topics')
topic = db.ReferenceProperty(Topic, required=True, collection_name='users') 
Reply all
Reply to author
Forward
0 new messages