views:

29

answers:

1

I need to change values for an entry, but the following code doesn't work.

logList = db.GqlQuery("SELECT * FROM Log ORDER BY date DESC LIMIT 1")
logList[0].content = "some text"
db.put(logList)

The value for the newest element doesn't change when I run this. I checked the output with Print, it gives correct value (to what the content field should be changed & the correct old value) and gives the following status code:

Status: 302 Moved Temporarily
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Location: http://localhost:8080/admin/editl
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Content-Length: 0

What is wrong with my code? The used method of altering data was mentioned in the official docs.

+2  A: 
logList = db.GqlQuery("SELECT * FROM Log ORDER BY date DESC LIMIT 1")
result = logList.get()
result.content = "some text"
result.put()

Try this. You are confusing the GqlQuery object for the results of actually eexecuting the query.

Adam Crossland
Actually, you can access the results using the iterator interface. Moreover, when the "LIMIT" clause is specified, then "results are retrieved as with the equivalent `fetch()` method." (ref: [GqlQuery docs](http://code.google.com/appengine/docs/python/datastore/gqlqueryclass.html#Introduction))
David Underhill
@David, he's not using the iterator interface; he is directly accessing an element of a suspected array. I don't know about the LIMIT=fetch() bit, but if I were him, I'd try what I suggested, as I think that his code looks a bit suspect to me. If he tries it and it doesn't work, I'll offer a bounty.
Adam Crossland
Your suggestion definitely works (+1) :). I guess the documentation means that the results are retrieved in the same way, but not returned in the way (i.e., the results are still returned as an iterable). Looks like the page he referenced in the docs needs to be updated - it definitely seems to suggest that his method should work. I suspect the `db.put(logList)` in his code is just re-retrieving the entities, and thus the put is just saving a freshly fetched, un-changed copy.
David Underhill
Adam, it worked! thanks :)
skazhy
Every time you treat a Query like an iterator or an array, the query is executed afresh. Results are not cached between accesses, so the logList entry he fetches and modifies on line 2 is not the same as the set of entities that are stored back to the datastore (unmodified!) on line 3.
Nick Johnson
@Nick: is that in the docs? While I never use the query-as-iterator/array pattern myself, I'll wager that many do, and it's likely causing some hidden performance problems.
Adam Crossland
Yes, it's documented. Per http://code.google.com/appengine/docs/python/datastore/queryclass.html: "As with fetch(), the iterator interface does not cache results, so creating a new iterator from the Query object will re-execute the query." I also blogged about it in my 'gotchas' post: http://blog.notdot.net/2009/11/Python-Gotchas
Nick Johnson
Yup, there it is right there. Cool, Nick, thanks.
Adam Crossland