Webware vs Spyce
Steve Holden
sholden at holdenweb.com
Fri Mar 21 17:06:31 EST 2003
"Tracker" <anonymous at microsoft.com> wrote in message
news:spvh7vg7ererbemjo1v925p1hlqj9r3imq at 4ax.com...
> On Mon, 17 Mar 2003 01:25:29 +0100, Gerhard Häring <gh at ghaering.de>
> wrote:
>
> >For invalid email addresses, please use the invalid TLD,
> >like nobody at nowhere.invalid.
>
> No, my news serwer will reject such no existing domain.
>
> >WebWare can be run in several settings (CGI, wrapper CGI, mod_python
> >integration, IIS integration, etc.). Spyce is AFAIK just a templating
> >engine that can be run under mod_python. AFAIK it doesn't even do
> >session handling.
>
> No, it is not true. Spyce do session handling, also CGI, mod_python or
> fast_cgi. It is no a templating system (although it has "spycelambdas"
> and integrate with other real template systems like Cheetah). It is
> rather embedded Python in HTML (like PHP is embedded in HTML code)
>
> >So to my knowledge, Webware is much more featureful.
> >
> >> I am also looking for Python equivalent of caching the SQL queries
> >> like ADOdb for PHP.
> >
> >I don't know about ADOdb or PHP,
>
> http://php.weblogs.com/ADODB
>
> >but isn't it some sort of database API?
>
> It is not only API (like PEAR or phpLib for PHP). ADOdb has several
> nice features beyound the basic API abstraction. Eg. it has real
> caching system for results extracted from databases.
>
> >The Python equivalent would then be the Python Database API
> >specification, for which there are many implementations for the popular
> >and less popular databases. See http://python.org/topics/database/
>
> They are nice, but they are no such powerfull like ADOdb. I found only
> this: http://csl.anu.edu.au/ml/dm/dm_software.html.
>
> >To be honest, I wouldn't how to "cache SQL queries". How would you know
> >you're not out of sync with the backend database?
>
> I can set up timeout of every query (eg. the cache will be refreshed
> every hour, or a day, or a week). I can also refresh it manually
> whetever I want. It works fine and for heavy sql queries it is very
> usefull.
>
I developed this (primitive) solution for "Python Web Programming". It might
be a starting point for you.
regards
Steve
import mx.DateTime
import dtuple
#################################################################
# $Revision: 7 $
# $Date: 10/19/01 1:37p $
#################################################################
class CacheQuery:
"""Defines a database query that caches database row sets.
This object is initialized with
tbl table name in the database
colnames list of field names retrieved
keynames list of keys used for retrieval
conn database connection
refresh caching refresh interval
Individual results are read by calling the object with a
tuple of key values as an argument. If the row set associated
with this particular set of keys is not present, or was read
longer than the refresh interval ago, it is re-read from the
database and stored in the content table as a list of database
tuples, which allow columns to be accessed by name.
Otherwise the already-cached database tuple set is returned.
Refinements might be added, such as registering with an
observer that might clear down all cache entries periodically
to force a global database refresh, and using a second SQL query
on record modified timestamps to determine whether a refresh is
really required (which may or may not be a win for a given set
of columns).
"""
def __init__(self, tbl, colnames, keynames, conn, refresh=0,
ORDER=None):
"""Create a caching data set for the given table, columns and
keys."""
self._flush()
self.tbl = tbl
self.keynames = keynames
self.refresh = refresh
self.cursor = conn.cursor()
self.sql = "SELECT %s FROM %s" % (",".join(colnames), tbl)
if keynames:
condition = " AND ".join(["%s=?" % f for f in keynames])
self.sql += " WHERE %s" % condition
if ORDER:
self.sql += " ORDER BY " + ", ".join(ORDER)
self.desc = dtuple.TupleDescriptor([[n, ] for n in colnames])
print "Descriptor:", self.desc
print "SQL:", self.sql
def _flush(self):
"""Remove all trace of previous caching."""
self.recs = {}
self.when = {}
def __call__(self, keyvals=(), debug=0):
"""Return the data set associated with given key values."""
assert len(keyvals) == len(self.keynames)
now = mx.DateTime.now()
if self.recs.has_key(keyvals) and self.refresh and (now -
self.when[keyvals] < self.refresh):
if debug: print "Interval:", now - self.when[keyvals]
return self.recs[keyvals]
else:
self.cursor.execute(self.sql, keyvals)
rows = self.cursor.fetchall()
result = [dtuple.DatabaseTuple(self.desc, row) for row in rows]
if self.refresh:
if debug: print "Caching", self.tbl, keyvals, " at", now
self.recs[keyvals] = result
self.when[keyvals] = now
return result
def close(self):
self.recs = None
self.when = None
self.cursor.close()
if __name__ == "__main__":
#
# Sorry, you'll need your own database details in here
#
import mx.ODBC.Windows as odbc
conn = odbc.connect("prom2000")
s1 = CacheQuery("department", # table
"DptName DptWelcome DptLnksTxt".split(), # columns
("DptCode",), # key
columns
conn, refresh=0) # other
stuff
while 1:
dc = raw_input("Department Code: ")
if not dc:
break
rows = s1((dc, ), debug=1)
if len(rows) == 0:
print "No such department"
else:
for row in rows:
print """
Department: %s Full Name: %s
Welcome Text:
%s
Links Text:
%s
""" % (dc, row.DptName, row.DptWelcome, row.DptLnksTxt)
s1.close()
conn.close()
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/pwp/
Register for PyCon now! http://www.python.org/pycon/reg.html
More information about the Python-list
mailing list