[Zope-dev] Re: ZSQL Methods in Z Classes

Shai Berger shai@aristocart.com
Mon, 21 May 2001 19:26:52 +0300


Hi Guys,

Last week, I wrote:
> 
> Hi Guys,
> 
> I wanted to use ZSQL Methods in Z Classes to share code between different
> parts of a large project. The different parts need to use similar, but
> separate, database namespaces, but I still wanted to use the same methods.
> 
[...]
> 
> I tried to bypass this limitation, by defining a forwarding database adapter.
> The idea was that this adapter's connection string would point to a resource
> (property or method) which will specify the actual connection. The idea was
> that in a ZClass, I could have this be a pythonscript which will look into
> an instance property sheet, thereby allowing different instances to use
> different connections.
> 
> This seemed to work very nicely at first: After the ZClass with the forwarding
> adapter and pythonscript was installed into a folder, all its methods worked
> like magic. I was very happy.
> 
> Then we restarted Zope, and ever since, it seems like the Adapter is being
> called by the ZSQL Methods without any acquisiotion context.
> 
Then we shut down Zope, and started it again from the command line, and everything
seems to work OK.

Except... that still,

> ZSQL Methods in the same class as the adapter act funny -- you
> can set it as their connection, but in the source they say "connection not found",
> and you can't test them in the class context (even when they don't rely on instance
> resources).
> 

And besides, my excellent adapter seems to have a problem:

The idea behind it is very simple. Most of the adapter code is taken from ZGadfly,
but the database implementation -- i.e. the connection between adapter and Python
binding -- is replaced with the function,

def DB(self, connection_finder):
    try: db_finder=getattr(self, connection_finder)
    except AttributeError:
        raise AttributeError, (
            "The database connection finder <em>%s</em> cannot be found." % (
            connection_finder))

    # db_finder may be a string or a method which returns a string
    if hasattr(db_finder,'__call__'):
        db_name = db_finder()
    else:
        db_name = db_finder
        

    # Now find the actual db
    try: db = getattr(self, db_name)
    except AttributeError:
        raise AttributeError, (
            "The database connection <em>%s</em> "
            "(indicated by <em>%s</em>) cannot be found." % (
            db_name, connection_finder))

    return db()

The function DB is called whenever there is need to fetch a new database connection.
It finds the name of the connection (db_name) and calls it, which is a lot like the
way ZSQL Methods themselves find their connections.

The problem is that when I try this with the proxied connection being a Z Oracle 
Connection, ZSQL methods in the ZClass get a different connection (at the Oracle
level) from those outside it; in my case, this leads to very unpleasant database 
locks. It looks to me like some bad case of acquisition illness, but I can't quite 
get a grip on it.

About ZSQL Methods in ZClasses:

Searching through the archives, I found that Lindell Alderman tried to do, essentially,
the same thing (use same set of ZSQL Methods on different connections thru ZClasses), 
and asked about it in zope-dev, exactly a year ago; there was no answer.
(http://zope.nipltd.com/public/lists/dev-archive.nsf/0a8715d5f3c7b6a3802568c1006328f7/
098f2c0745ca099c802568e6007f2f31?OpenDocument&Highlight=2,ZClass)

Is there a non-ZClass way to do this?

Thanks again, and sorry for my impatience -- I really didn't want to share Lindell's
fate of being unanswered, so I figured at least I could reply...

Have fun,
	Shai.