2011-06-14 6 views
6

मैं एक ऐप बना रहा हूं जो सामूहिक.लेड (ट्रंक) का उपयोग करके बाह्य संबंध डेटाबेस में कुछ डेटा पूछता है। उपयोगकर्ता एक कस्टम प्लोन कंट्रोल पैनल टूल में डेटाबेस कनेक्शन सेटिंग्स को संशोधित कर सकता है (मैंने एस्पेल की व्यावसायिक प्लोन डेवलपमेंट बुक में उदाहरण का पालन किया)। डेटाबेस सेटिंग्स इस तरह से पूछताछ की जाती है।घटक लुकअप स्टार्टअप समय पर रजिस्ट्री से पूछताछ करते समय त्रुटि

मेरे उत्पाद के आधार 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" 
    /> 

रनटाइम पर रजिस्ट्री क्यों नहीं मिली है? मैं क्या गलत कर रहा हूं?

धन्यवाद।

उत्तर

5

स्टीव का उल्लेख समस्या की जड़ है, इसलिए मैं केवल उन मामलों के लिए एक समाधान जोड़ूंगा जहां आप अपवाद हैंडलिंग नहीं कर सकते हैं। इसी तरह के परिदृश्य में मुझे एक उपयोगिता पंजीकृत करने की आवश्यकता थी जो रजिस्ट्री में संग्रहीत सेटिंग्स पर निर्भर था। इन सेटिंग्स के बिना उपयोगिता पंजीकृत नहीं की जा सकी, इसलिए मैं पूरी तरह से चीजों को क्रम में करना चाहता था।

वैकल्पिक हल नहीं के लिए गया था रजिस्टर zcml में उपयोगिता, लेकिन इसके बजाय निम्नलिखित ग्राहक के अंदर यह करना:

<subscriber 
    for="Products.CMFPlone.interfaces.IPloneSiteRoot 
     zope.app.publication.interfaces.IBeforeTraverseEvent" 
    handler=".component.setupStuff" 
    /> 

इस बात की गारंटी है कि setupStuff सभी स्थानीय उपयोगिताओं के लिए उपयोग किया जाएगा। ध्यान दें कि setupStuff पूछताछ के तुरंत बाद वापस आ जाएगा अगर उपयोगिता पहले से मौजूद है, क्योंकि ग्राहक प्रत्येक अनुरोध पर ट्रिगर करेगा।

+0

धन्यवाद। यह सबसे साफ समाधान है। – zedr

5

रजिस्ट्री एक स्थानीय घटक है। प्रत्येक प्लोन साइट (और डेटाबेस में कई हो सकते हैं) का अपना स्वयं का है। तो, यह संदर्भ निर्भर है।

ज़ोप ट्रैवर्सल (किसी ऑब्जेक्ट को यूआरएल को जोड़ने) के दौरान उस संदर्भ को दर्शाता है। वह (बहुत अधिक) का अर्थ है कि आप केवल अनुरोध के संदर्भ में रजिस्ट्री को देख सकते हैं। तो, आप स्टार्टअप कोड में रजिस्ट्री को नहीं देख सकते हैं।

इससे चिकन-एंड-अंडे समस्याएं कोड लिख सकती हैं। एक समाधान लुकअप को एक कोशिश में एम्बेड करना है/सिवाय इसके कि यदि आप अभी तक ट्रैवर्सल संदर्भ नहीं रखते हैं तो लुकअप अपवाद को सुदृढ़ रूप से संभालता है।

+0

अंतर्दृष्टि के लिए धन्यवाद। मैंने वास्तव में कोशिश करके समस्या को कम कर दिया: सिवाय इसके कि: क्लॉज जो चुपचाप त्रुटि को तब तक पास करने देता है जब तक ऑब्जेक्ट किसी संदर्भ को प्राप्त नहीं करता। – zedr

6

collective.lead को http://pypi.python.org/pypi/z3c.saconfig से हटा दिया गया है जो आपको zcml में डेटाबेस कनेक्शन को परिभाषित करने की अनुमति देता है। यदि आपको कनेक्शन कॉन्फ़िगर करने के लिए नियंत्रण कक्ष की आवश्यकता है तो इसका उपयोग http://pypi.python.org/pypi/collective.saconnect के साथ किया जा सकता है।

संबंधित मुद्दे