<snip>
> I went another route in my prototype and I'd like to hear some
> comments:
>

No shortage of opinions here!

> I have a class "Product" that represents a Product:
>
>> start py code
> class Product:
>        def __init__(self, id):
>                db = datapool.getConnection()
>                c = db.cursor()
>                q = '''select * from NORMAL where (id = %d)''' % id
>                c.execute(q)
>                res = c.fetchone()
>                description = c.description
>                self.data = {}
>                if res:
>                        for i in range(len(description)):
>                                self.data[description[i][0]] = res[i]
>                db.close()
>> end py code
>
> The Product has methods for pretty-printing and such. Then there is a
> class  for a ProductSelection, which basically is a list of IDs, *but*
> it also limits the results and does the stepping:
>
>> start py code
> class ProductSelection:
>        def __init__(self, clause=''):
>                self.productIds = self.selectByClause(clause)
>
>       def selectByClause(self, clause='', start=0, count=10):
>               if clause:
>                       db = datapool.getConnection()
>                       c = db.cursor()
>                       q = '''select id from normal where (%s) order by artist''' % 
>clause
>                       c.execute(q)
>                       # where do we start?
>                       startcount = start * count
>                       # where's the end, add 1, to see if there are
>                       # more results after this set:
>                       endcount   = startcount + count + 1
>                       res = c.fetchall()[startcount:endcount]
>                       db.close()
>                       return res
>               else:
>                       return []
>> end py code
>
> Now in the Page code, this is easy to use:
>
>> start py code
>       stepsize = 10   # global stepsize variable
>       startWhere = int(self.request().value("startProducts"))
>       ps = ProductSelection(someClause, start=startWhere, count=stepsize )
>       for id in ps.productIds[:-1]:
>               p = Product(id)
>               p.show()
>
>       if len(ps.productIds) > stepsize:
>               stpplus = stp + 1
>               self.writeln('''
>               <a href="?startProducts=%s"><b>To the Next %s results</b></a>
>               ''' % (stpplus, stepsize))
>
>> end py code
>
>
> Now my hope is (I didn't profile it, yet), that this is fast enough,
> because the IDs are int fields and in the worst case ("select * from
> NORMAL") I have a c.fetchall() that returns 40.000 ints. But this is
> sliced to be in a range [startcount:endcount], so it actually is only
> used for a very short time, if at all, isn't it?
>
> OTOH I have another select for every Product and there might be a lot
> of Products in memory. At least, we hope that people look at the
> Products a lot... :)
>
> ciao
> --
> Frank Barknecht                               _ ______footils.org__
>

This is one of the areas where Webware/Python really shines and you can do a
lot of optimizations here with relatively little effort.

The product class looks good, but I would take a look at the selectot class.
 It looks to me that for each page you are:
1) creating a new instance of a python
2) Pulling lots of data from a sql db
3) Pulling all of the records from the native sql format into python
4) Slicing that array.

A couple of ideas
1) Cache the instance of ProductSelection in the users session and only go
back to the database if the 'clause' changes. (Stick the full resultset in
self._results and slice on that.
... Updates to the database will only be seen by new users, since old ones
will be looking at a snapshot
2) Follow version 1, but store in an application level cache.  There are
some good caching routines out there. You can set it up to store a result
set for 30 min or something like that.
3) Mixin ProductSelection to SitePage, and then pass the start and stop
right to the SQL and pull only the interesting records. (lose the init and
call self.selectByClause)

Finally: replace all of the self.writeln's w/ a few good cheetah template
fragments.  It will make life easier when batching.

If you are using mysql w/ simple clauses then you should have no problem
going to sql for each page.  I make extensive use of caching when the SQL
calls take a long time (seconds) or there are complex transformations (xml)
involved.

-Aaron Held




-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Webware-discuss mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/webware-discuss

Reply via email to