我正在构建一个应用程序,它使用collective.lead (主干)查询外部关系数据库中的一些数据。用户可以在自定义Plone控制面板工具中修改数据库连接设置(我遵循了Aspeli的Professional Plone Development一书中的示例)。通过这种方式查询数据库设置。
我的产品的基础configure.zcml为数据库设置了一个实用程序:
<include package="plone.app.registry" />
<include package="collective.lead" />
<i18n:registerTranslations directory="locales" />
<utility
provides="collective.lead.interfaces.IDatabase"
factory=".dbsettings.CalculatorDatabase"
name="test.calc.db"
/>dbsettings.py具有:
from zope.component import getUtility
from plone.registry.interfaces import IRegistry
class CalculatorDatabase(Database):
@property
def _url(self):
registry = getUtility(IRegistry)
settings = registry.forInterface(IDatabaseSettings)
return URL(
drivername=settings.drivername,
username=settings.username,
password=settings.password,
host=settings.hostname,
port=settings.port,
database=settings.database,
)这将在运行时引发ComponentLookupError异常:
File "/home/zope/envs/test-web/src/test.calc/test/calc/dbsettings.py", line 38, in _url
registry = getUtility(IRegistry)
File "/home/zope/envs/test-web/eggs/zope.component-3.7.1-py2.6.egg/zope/component/_api.py", line 171, in getUtility
raise ComponentLookupError(interface, name)
zope.configuration.config.ConfigurationExecutionError: <class 'zope.component.interfaces.ComponentLookupError'>: (<InterfaceClass plone.registry.interfaces.IRegistry>, '')
in:
File "/home/zope/envs/test-web/src/test.calc/test/calc/configure.zcml", line 26.2-30.6
<utility
provides="collective.lead.interfaces.IDatabase"
factory=".dbsettings.CalculatorDatabase"
name="test.calc.db"
/>为什么在运行时找不到注册表?我做错了什么?
谢谢。
发布于 2011-06-15 00:28:03
Steve提到的是问题的根源,所以我将只为您无法进行异常处理的情况添加一个变通方法。在类似的场景中,我需要注册一个依赖于注册表中存储的设置的实用程序。如果没有这些设置,该实用程序就无法注册,所以我绝对希望事情按顺序发生。
解决方法是不在zcml中注册该实用程序,而是在以下订户中注册:
<subscriber
for="Products.CMFPlone.interfaces.IPloneSiteRoot
zope.app.publication.interfaces.IBeforeTraverseEvent"
handler=".component.setupStuff"
/>这将保证setupStuff可以访问所有本地实用程序。还要注意,在查询实用程序是否已经存在后,setupStuff也会快速返回,因为订阅者将在每次请求时触发。
发布于 2011-06-15 03:34:48
collective.lead已经被http://pypi.python.org/pypi/z3c.saconfig所取代,后者允许您在zcml中定义数据库连接。如果您需要控制面板来配置连接,它可以与http://pypi.python.org/pypi/collective.saconnect一起使用。
发布于 2011-06-15 00:12:20
注册表是一个本地组件。每个Plone站点(数据库中可能有许多)都有自己的站点。因此,它依赖于上下文。
Zope在遍历(将URL连接到对象)的过程中计算出上下文。这(很大程度上)意味着您只能在请求上下文中查找注册表。因此,您不能在启动代码中查找注册表。
这可能会导致编写代码时先有鸡还是先有蛋的问题。一种解决方案是,如果还没有遍历上下文,则将查找嵌入到try/except中,以便优雅地处理查找异常。
https://stackoverflow.com/questions/6346391
复制相似问题