I'd appreciate any insight into the best design for this problem.  I
have a photo-sharing app.  I want people to be able to mark a photo as
a "favourite", just as YouTube does with videos.

I have two kinds: Snapshots and Users.  Given a user, I need to be
able to get a list of their favourites, and a list of the snapshots
they created.  I need the inverse too, i.e. given a snapshot, I need
to know who made it.

The problem I have is ensuring consistency across these two kinds, but
I don't think I can put them into the same entity group.  First, here
they are:

# The snapshot class.
class SS(db.Model):
    owner = db.StringProperty(indexed=False) # Who created this (user
id).
    #Other data about the snapshot here

# The user class (the key_name is the user id)
class User(db.Model):
    owned_ids = db.ListProperty(int, indexed=False) # IDs of owned
snapshots (i.e. created by this user)
    fav_ids = db.ListProperty(int, indexed=False)       # IDs of
favourite snapshots

The issue is that when a user either creates or deletes a snapshot,
there's a potential for those to get out of sync if an exception
happens just at the wrong moment (e.g. a snapshot could exist where
the creating user doesn't have it in the owned_ids list).

Making a User instance the parent of a SS (snapshot) instance seems
like a natural fit, except then I can't fetch all the favourites via:
favs = SS.get_by_id(user.fav_ids).  The reason is that all parents
have to be the same to use SS.get_by_id (according to
http://code.google.com/appengine/docs/python/datastore/modelclass.html#Model_get_by_id),
but those favourites may have been created by various users (hence the
parents would be different).

Originally I had no owned_ids in User, and did a query to find that
user's snapshots (owner in SS was indexed).  But that was slow and
didn't lend itself to paging.  So I switched to get_by_id.

Documentation note: run_in_transaction at
http://code.google.com/appengine/docs/python/datastore/functions.html
doesn't mention the restriction that entities have to be in the same
group.  I discovered it by seeing the exception, then read up in more
detail elsewhere.  I naturally started there so it probably should be
mentioned.

-- 
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-appeng...@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