On Wed, 2003-07-16 at 20:22, Ian Bicking wrote:
> On Wed, 2003-07-16 at 08:37, Matt Goodall wrote:
> > If you have code like this
> > all = Entity.select('all')
> > for i in range(len(all)):
> > print all[i]
> > you get a whole stream of SQL calls. For a table with n rows you
> > actually get 2n+1 SQL calls: 1 initial COUNT(*) and then a COUNT(*) and
> > SELECT for each row.
> > It makes sense for a SelectResults objects to cache the COUNT result on
> > the first len() so that future len() calls don't go back to the database?
> Huh... I don't know why it's creating lots of COUNT calls. Is it
Yes. It seems to be the last line of SelectResults.__getitem__ that is
causing this, not sure why at the moment otherwise I'd send a patch.
> It would, though, create a bunch of SELECTs, like SELECT blah
> LIMIT 1 OFFSET 0, SELECT blah LIMIT 1 OFFSET 1, etc.
> The problem is the way you're using it.
Unfortunately, it's not my code - it's another package that is walking
the list using an index. I can probably change that package but
couldn't/shouldn't SQLObject be a bit more graceful under these
To be honest, it's really the multiple COUNT calls that bother me as it
seems unnecessary. The multiple SELECT calls to retrieve the objects are
to be expected but can possibly be avoided.
> You should iterate directly
> over the result, or force getting everything at once by doing list(all).
> Like either:
> all = list(Entity.select())
> for i in range(len(all)):
> print all[i]
This is effectively how I am working around the "problem" for now, by
passing a list() rather than a SelectResults.
> # or:
> all = Entity.select()
> for i, obj in enumerate(all):
> print obj
I'm not sure I see the benefit of this. Doesn't SQLObject already use a
generator to walk the result of the query? Wouldn't this just wrap one
generator in another?
Matt Goodall, Pollenation Internet Ltd