Stephan Richter wrote:
On Tuesday 08 November 2005 05:38, Andreas Elvers wrote:
Has anyone yet tried sqlos with database connections created as local
utilities ? At one point sqlos tries to get the utility in
Line 88.

 newconn = zapi.queryUtility(IZopeDatabaseAdapter, name,

The context points to a sqlobject instance. The problem is that these
instances seem to have no parent and thus will fail the lookup my local
utility and will raise an 'NoneType' object is not callable error later
in the code when trying to adapt.

When you try the sqlos example everything is fine, since the database
connection is defined in configure.zcml as a global utility.

My current idea is to expose the enclosing folder as a context to query
utility. But I don't know if setting references in sqlobject instances
is such a great idea.

If the sqlobject instance does not have a parent, then that's bad. It probably does not have a parent, because it is usually wrapped using a location proxy, which is lost inside a method. I think the smart thing to do here would be what you suggested or to write a subclass of sqlobject that implements ILocation.


While digging a bit depper into my problem I found out, that implementing ILocation will not do the trick, since the mentioned exception is caused by a factory call, and
a factory will never have a __parent__ or am I totally wrong here ?

Anyway I have created a functional unit test to demonstrate the problem. In fact the unit test shows that sqlos will always lookup global utilities and never local utilities.

Here is the test. It will fail in the last block on "testsite['personcontainer'] = personcontainer".

- Andreas

First we need to set up some folder structure to set up a site.

    >>> from import zapi
    >>> from import Folder
    >>> from import Contained
    >>> from sqlos.testing.sampleperson import SamplePersonContainer, 
    >>> from import interfaces as componentInterfaces
    >>> from import 
    >>> from sqlos.container import SQLObjectContainer

    >>> class LocalSitePersonContainer(SamplePersonContainer, 
SiteManagerContainer, Contained):
    ...    pass

    >>> root = getRootFolder()
    >>> testsite = Folder()
    >>> root['testsite'] = testsite
    >>> componentInterfaces.ISite.providedBy(testsite)

    >>> sm = LocalSiteManager(testsite)
    >>> testsite.setSiteManager(sm)
    >>> componentInterfaces.ISite.providedBy(testsite)

Now we set up a local database utility

    >>> from import IZopeDatabaseAdapter
    >>> from import 
    >>> from sqlos.testing.testdb import SQLiteda
    >>> from import UtilityRegistration

    >>> dbAdapter = SQLiteda(u'dbi://:memory:') 
    >>> reg = UtilityRegistration('sqlite',IZopeDatabaseAdapter,dbAdapter)
    >>> default = sm['default']
    >>> key = default.registrationManager.addRegistration(reg)
    >>> zapi.traverse(default.registrationManager, key).status = ActiveStatus

    >>> localUtility = sm.queryUtility(IZopeDatabaseAdapter,'sqlite')
    >>> localUtility
    <sqlos.testing.testdb.SQLiteda object at ...>

    >>> localUtility is dbAdapter

Ok. Now we have a site in root/testsite with a registered sqlite adapter.
We make sure that our localUtility is not identical to the global sqlite utility
that has been registered through ftesting.zcml.

    >>> gsm = zapi.getGlobalSiteManager()
    >>> globalUtility = gsm.queryUtility(IZopeDatabaseAdapter,'sqlite')
    >>> globalUtility is not localUtility

Now we populate testsite with data. We do this by using direct SQL, because 
there is currently
no support for local sites in testcode.

    >>> from zope.component.interfaces import ISiteManager

    >>> cursor = localUtility().cursor()

    >>> cursor.execute(
    ...         '''create table dog (
    ...                   id integer primary key,
    ...                   fullname varchar(50) not null,
    ...                   owner varchar(20) not null)''')
    >>> cursor.execute(
    ...         '''create table sample_isolated_person (
    ...                   id integer primary key,
    ...                   domains text,
    ...                   fullname varchar(50) not null,
    ...                   username varchar(20) not null,
    ...                   password varchar(20) not null)''')
    >>> cursor.execute(
    ...         '''create table sample_person (
    ...                       id integer primary key,
    ...                   fullname varchar(50),
    ...                   username varchar(20),
    ...                   password varchar(20))''')

Now that we have setup database tables we should be able to create the 
personcontainer without errors.

    >>> personcontainer = LocalSitePersonContainer()
    >>> testsite['personcontainer'] = personcontainer
    >>> localUtility2 = 
    >>> localUtility2 is localUtility


Zope3-users mailing list

Reply via email to