Registry 启动时查询注册表时的ComponentLookupError

Registry 启动时查询注册表时的ComponentLookupError,registry,plone,zope,Registry,Plone,Zope,我正在构建一个应用程序,使用collective.lead(trunk)查询外部关系数据库中的一些数据。用户可以在自定义Plone控制面板工具中修改数据库连接设置(我遵循了Aspeli的专业Plone开发书中的示例)。以这种方式查询数据库设置 我的产品的base configure.zcml为数据库设置了一个实用程序: dbsettings.py具有: 从zope.component导入getUtility 从plone.registry.interfaces导入IRegistry 类计算器

我正在构建一个应用程序,使用collective.lead(trunk)查询外部关系数据库中的一些数据。用户可以在自定义Plone控制面板工具中修改数据库连接设置(我遵循了Aspeli的专业Plone开发书中的示例)。以这种方式查询数据库设置

我的产品的base configure.zcml为数据库设置了一个实用程序:


dbsettings.py具有:

从zope.component导入getUtility
从plone.registry.interfaces导入IRegistry
类计算器数据库(数据库):
@财产
定义url(自):
注册表=getUtility(IRegistry)
设置=注册表.forInterface(IDatabaseSettings)
返回URL(
drivername=settings.drivername,
username=settings.username,
password=settings.password,
host=settings.hostname,
port=settings.port,
database=settings.database,
)
这会在运行时引发ComponentLookupError异常:

文件“/home/zope/envs/test web/src/test.calc/test/calc/dbsettings.py”,第38行,在
注册表=getUtility(IRegistry)
文件“/home/zope/envs/test web/eggs/zope.component-3.7.1-py2.6.egg/zope/component/_api.py”,第171行,在getUtility中
raise ComponentLookupError(接口、名称)
zope.configuration.config.ConfigurationExecutionError::(,“”)
在:
文件“/home/zope/envs/test web/src/test.calc/test/calc/configure.zcml”,第26.2-30.6行
为什么在运行时找不到注册表?我做错了什么


谢谢。

注册表是本地组件。每个Plone站点(数据库中可能有许多站点)都有自己的站点。所以,它是上下文相关的

Zope在遍历(URL与对象的连接)过程中找出了上下文。这(基本上)意味着您只能在请求的上下文中查找注册表。因此,您不能在启动代码中查找注册表


这可能导致编写代码时出现鸡和蛋的问题。一种解决方案是将查找嵌入到try/except中,如果您还没有遍历上下文,它可以优雅地处理查找异常。

Steve提到的是问题的根源,因此我只为无法处理异常的情况添加一种变通方法。在类似的场景中,我需要注册一个依赖于注册表中存储的设置的实用程序。没有这些设置,该实用程序无法注册,因此我绝对希望事情按顺序进行

解决方法是不在zcml中注册该实用程序,而是在以下订阅服务器中注册:



这将保证
setupStuff
可以访问所有本地实用程序。还请注意,查询实用程序是否已存在后,
setupStuff
也会快速返回,因为订阅者会在每次请求时触发。

collective.lead已被取代,它允许您在zcml中定义数据库连接。如果您需要一个控制面板来配置连接,它可以与一起使用。

谢谢。这是最干净的解决方案。感谢您的洞察力。我确实通过添加一个try:except:子句缓解了这个问题,该子句在对象获取上下文之前一直让错误通过。