This is done on the backend, if I remember correctly. It doesn't gain you anything.
On Wed, Sep 7, 2011 at 19:28, Joshua Smith <[email protected]> wrote: > Continuing the dialog with myself :) > > I've added this method to one of my classes that extends db.Model() and it is > working well with the dev appserver in --high_replication mode: > > @classmethod > def gql_with_get(cls, query_string, *args, **kwds): > return db.get(db.GqlQuery('SELECT __key__ FROM %s %s' % (cls.kind(), > query_string), *args, **kwds)) > > You use it just like gql().fetch(). For example: > > boards = BoardModel.gql_with_get("WHERE towns = :1 ORDER BY name", tid) > > It doesn't fix the index (things might be out of order, for instance), but > otherwise, it cures the problem of seeing stale data in HR. > > On Sep 7, 2011, at 12:22 PM, Joshua Smith wrote: > >> Another thought: The reason I was doing only one meeting per request was >> because of the old 30 second limit on crons. But cron handlers can be 10 >> minutes now, which is plenty of time to schedule all the meetings. >> Therefore, I suppose I could do this, right? >> >> now = datetime.datetime.now() >> for schedule in db.get(db.gql("SELECT __key__ FROM ScheduleModel WHERE >> next != :1 AND next < :2", None, now)): >> if schedule.next and schedule.next < now: >> schedule.cronAuto() >> >> Is wrapping a GET around a KEYS-ONLY query guaranteed to get me the >> real-deal results (except, of course, for the fact that the index might be >> out-of-date, so I might miss recent changes to who is in/out of the query >> parameters)? Is this an efficient way to express this, or should I be doing >> a fetch() on the gql first? >> >> It seems like it's possible to use a technique like this to get a >> more-consistent result in cases where that's desirable. It at least would >> get you a consistent data for a subset of things matching your query. In >> principle, you could even re-sort the results if there is an ORDER clause. >> Seems like this would be something useful in the db API... >> >> -Joshua >> >> On Sep 7, 2011, at 11:18 AM, Joshua Smith wrote: >> >>> >>> I'm trying to port my existing M/S app to HR because I have a gun to my >>> head with "Threaded Python Only for HR Apps" written on the bullets. >>> >>> My system will schedule meetings automatically. Scheduling a meeting can >>> take some time, because a bunch of records are created, and a bunch of >>> emails need to go out. So the code to schedule one looked like this: >>> >>> class MeetingAutoHandler(webapp.RequestHandler): >>> def get(self): >>> schedule = ScheduleModel.gql("WHERE next != :1 AND next < :2", None, >>> datetime.datetime.now()).get() >>> if schedule: >>> schedule.cronAuto() >>> taskqueue.add(url='/admin/meetingAuto', method='GET', countdown=1) >>> >>> The query looks for a schedule object that needs a meeting to to be >>> scheduled now. There might be a few of these when the cron runs. So it >>> does the hard work for one of them (in cronAuto()), and schedules another >>> call to itself to get the next one using the task queue. >>> >>> This isn't going to work in HR because that query is going to keep finding >>> the same meeting. I could trivially tweak this by setting the >>> countdown=60, but I've yet to hear any of our google overlords commit to a >>> maximum value of when "eventually" happens in "eventually consistent". I >>> presume there might be cases, like during data center transitions, when >>> "eventually" could be a very long time indeed. It is essentially >>> unbounded. Right? >>> >>> But I like the pattern I'm using here, and I'm trying to change as little >>> code as possible, so I want to put together a HR-resilient version. Here's >>> what I came up with: >>> >>> class MeetingAutoHandler(webapp.RequestHandler): >>> def get(self): >>> now = datetime.datetime.now() >>> for s in db.gql("SELECT __key__ FROM ScheduleModel WHERE next != :1 AND >>> next < :2", None, now): >>> schedule = db.get(s) >>> if schedule.next and schedule.next < now: >>> schedule.cronAuto() >>> taskqueue.add(url='/admin/meetingAuto', method='GET', countdown=5) >>> return >>> >>> So I'm doing a keys-only query and then doing a get() on the key. (I've >>> never done a keys-only GQL query before, but I think I got it right. Note >>> to google: There should be an option to Model.gql() to do keys-only >>> queries!) >>> >>> The way I understand HR, that get is going to get the real Model, which >>> might not meet the criteria in the gql, because the index might be out of >>> date. Right? >>> >>> So I check that the model meets the criteria that I just specified. (Note >>> to google: It'd be cool if there was a way to test an object against a >>> query, so I don't have to write the same code twice!) >>> >>> Finally, I pushed the next task out a bit, to make it less likely that I'll >>> have to look at the same objects over and over. >>> >>> So what do you think? Any suggestions? (I have a couple things that work >>> this way, so I want to choose a good design pattern to apply to each of >>> them.) >>> >>> The complexity would be lessened if I could to this: >>> >>> class MeetingAutoHandler(webapp.RequestHandler): >>> def get(self): >>> q = ScheduleModel.gql_keys_only("WHERE next != :1 AND next < :2", None, >>> datetime.datetime.now()) >>> for s in q: >>> schedule = db.get(s) >>> if q.matches(schedule): >>> schedule.cronAuto() >>> taskqueue.add(url='/admin/meetingAuto', method='GET', countdown=5) >>> return >>> >>> This would require two changes: the db.Model would need to support >>> gql_keys_only (that's probably trivial); GqlQuery would need a matches() >>> method (that's probably not trivial). >>> >>> It's still a few more lines, but the complexity is about the same as the >>> old one. >>> >>> Worth the trouble of a couple feature request issues? >>> >>> -Joshua >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Google App Engine" group. >>> To post to this group, send email to [email protected]. >>> To unsubscribe from this group, send email to >>> [email protected]. >>> For more options, visit this group at >>> http://groups.google.com/group/google-appengine?hl=en. >>> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Google App Engine" group. >> To post to this group, send email to [email protected]. >> To unsubscribe from this group, send email to >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/google-appengine?hl=en. >> > > -- > You received this message because you are subscribed to the Google Groups > "Google App Engine" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/google-appengine?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
