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 connection.py
Line 88.
newconn = zapi.queryUtility(IZopeDatabaseAdapter, name,
default=None,
context=context)
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.
Hi,
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.
Regards
- Andreas
First we need to set up some folder structure to set up a site.
from zope.app import zapi
from zope.app.folder import Folder
from zope.app.container.contained import Contained
from sqlos.testing.sampleperson import SamplePersonContainer,
createTestingTables
from zope.app.component import interfaces as componentInterfaces
from zope.app.component.site import
LocalSiteManager,SiteManagerContainer
from sqlos.container import SQLObjectContainer
class LocalSitePersonContainer(SamplePersonContainer,
SiteManagerContainer, Contained):
...pass
root = getRootFolder()
testsite = Folder()
root['testsite'] = testsite
componentInterfaces.ISite.providedBy(testsite)
False
sm = LocalSiteManager(testsite)
testsite.setSiteManager(sm)
componentInterfaces.ISite.providedBy(testsite)
True
Now we set up a local database utility
from zope.app.rdb.interfaces import IZopeDatabaseAdapter
from zope.app.component.interfaces.registration import
ActiveStatus,InactiveStatus
from sqlos.testing.testdb import SQLiteda
from zope.app.utility 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
True
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
True
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