views:

168

answers:

3

Using the following models I am trying to figure out a way to generate a news feed of sorts so that when a user logs in they are presented with a list of upcoming events for bars that they choose to follow. Will I be able to query something like “SELECT * FROM Barevent WHERE parent_bar IN UserprofileInstance.following”? If so will this be efficient?

class Barprofile(db.Model):
    b_user          = db.UserProperty()
    created         = db.DateTimeProperty(auto_now_add=True)
    barname         = db.StringProperty()
    address         = db.PostalAddressProperty()
    zipcode         = db.StringProperty()

class Barevent(db.Model):
    created         = db.DateTimeProperty(auto_now_add=True)
    when            = db.DateProperty()
    starttime       = db.TimeProperty()
    endtime         = db.TimeProperty()
    description     = db.StringProperty(multiline=True)
    parent_bar      = db.ReferenceProperty(Barprofile, collection_name='bar_events')

class Userprofile(db.Model):
    b_user          = db.UserProperty()
    following       = db.ListProperty(db.Key)
A: 

There are a lot of ways to do GAE queries but I don't see why yours wouldn't work. If you had a specific Barprofile (B) then I think you could (in Python) do;

   query = db.GqlQuery("SELECT * FROM Barevent WHERE parent_bar = :1,
                            B.b_user)
   day = query.get()

But I'm not quite sure why you have both a Userprofile and a Barprofile (so I think you'd want to reconsider those three).

Generally, you don't need (or even want) to normalize data in GAE as you're used to doing for traditional RDBMS environments. There's no particular advantage to normalizing your data that way anymore, i.e. instead of making it up to your DB to ensure consistency you do it at the application level now.

jay
A: 

Your model and your query should work fine, and it would not be inefficient. The one thing that you will want to keep in mind is that if Barprofile entities are deleted, you may want to manually remove their keys from the following property of each Userprofile. Having an orphaned Barprofile reference will not break the query, but if you ever use that list for other purposes (such as displaying to a user which bars he or she is subscribed to), you will got an error if you try to query on that key.

Adam Crossland
Thank you Adam. I just needed some confirmation that I was on the right track.
riltim
A: 

The structure you're describing will work, but bear in mind that the 'IN' operator requires executing one query for each item in the list - so it could result in a lot of queries.

However, what you're dealing with is a 'scatter-gather' problem akin to Twitter, so you don't have much choice - you either gather things at read time like this, or you broadcast them to all listening users at update time.

Nick Johnson
Thank you for the confirmation Nick, I was afraid that this could generate a lot of queries. I'll have to rack my brain to see if I can find an efficient way to cache some of this.
riltim