Webware vs Spyce

Steve Holden sholden at holdenweb.com
Fri Mar 21 23:06:31 CET 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