[Zope3-Users] adding indexes in a __init__ method

Lorenzo Gil Sanchez lgs at sicem.biz
Tue Jul 25 07:55:21 EDT 2006


Hi Darryl,

this is how I ended implementing it:


class FilterableContainer(BTreeContainer):

    implements(IFilterableContainer)

    def __init__(self, catalog=None):
        super(FilterableContainer, self).__init__()
        self.catalog = contained(LocalCatalog(), self, 'catalog')

    def createIndexes(self):
        self.catalog['attr1'] = FieldIndex('attr1')
        self.catalog['attr2'] = FieldIndex('attr2')


def onFilterableContainerAdded(obj, event):
    if IFilterableContainer.providedBy(obj):
        obj.createIndexes()


Thanks a lot for your help and suggestions!

Lorenzo

El mar, 25-07-2006 a las 22:38 +1200, Darryl Cousins escribió:
> Hi Lorenzo,
> 
> I got this test to work::
> 
>     >>> class TestField(Persistent):
>     ...     pass
> 
>     >>> class TestCase(Persistent):
>     ...     def __init__(self):
>     ...         self.fieldkey = KeyReferenceToPersistent(TestField())
> 
>     >>> t = TestCase()
>     Traceback (most recent call last):
>     ...
>     NotYet:...
> 
>     >>> class TestCaseTwo(Persistent):
>     ...     def __init__(self):
>     ...         self.field = TestField()
>     ...     def initfield(self):
>     ...         self.fieldkey = KeyReferenceToPersistent(self.field)
>     ...         del(self.field)
> 
>     >>> t = TestCaseTwo()
>     >>> tc = root['t'] = t
> 
>     >>> transaction.commit()
>     >>> tc.initfield()
>     >>> print tc.field
>     Traceback (most recent call last):
>     ...
>     AttributeError:...
> 
> (Set up for test is shown in 
> 
> Which would mean that if you created the FieldIndex in __init__ and the
> catalog[key] part in the initialization handler then it should work.
> 
> I put the del(self.field) bit in as a test in case you don't want that
> attribute unecessarily hanging around.
> 
> Hope **that** helps.
> 
> Regards,
> Darryl
> 
> On Tue, 2006-07-25 at 12:24 +0200, Lorenzo Gil Sanchez wrote:
> > No worries, in fact I actually tried the same aproach and hit the same
> > problem
> > 
> > Thanks anyway
> > 
> > Lorenzo
> > 
> > El mar, 25-07-2006 a las 22:16 +1200, Darryl Cousins escribió:
> > > Hi again,
> > > 
> > > I was a too hasty. Because it is the FieldIndex that is missing the
> > > _p_oid attribute, and the fix I offered is for the container. Sorry
> > > about that.
> > > 
> > > I need more thinking.
> > > 
> > > Regards,
> > > Darryl
> > > 
> > > 
> > > On Tue, 2006-07-25 at 22:10 +1200, Darryl Cousins wrote:
> > > > Hi Lorenzo,
> > > > 
> > > > The key reference adapter can only get a key reference **after** the
> > > > object is added to the database (because it uses _p_oid).
> > > > 
> > > > The problem could be fixed with a subscriber to IObjectAddedEvent::
> > > > 
> > > >   def FilterableContainerInitializationHandler(object, event):
> > > >       """Initialize container after its ObjectAddedEvent."""
> > > > 
> > > > 	# I have checks here too (maybe unecessary)
> > > > 	if not IObjectAddedEvent.providedBy(event):
> > > > 		return
> > > > 	if not IFilterableContainer.providedBy(object):
> > > > 		return
> > > >       	# whatever needs to be done
> > > > 	# self._catalog ...
> > > > 
> > > > This handler is configured::
> > > > 
> > > >   <!-- initialization handler -->
> > > >   <subscriber
> > > >     for=".IFilterableContainer
> > > >          zope.app.container.interfaces.IObjectAddedEvent"
> > > >     handler=".subscribers.FilterableContainerInitializationHandler"
> > > >     />
> > > > 
> > > > Hope that helps.
> > > > 
> > > > Best regards,
> > > > Darryl
> > > > 
> > > > On Tue, 2006-07-25 at 11:26 +0200, Lorenzo Gil Sanchez wrote:
> > > > > Hi,
> > > > > 
> > > > > I have a special Folder content. When an instance of this class is
> > > > > created I want to create a catalog and an index in its __init__ method.
> > > > > Something like:
> > > > > 
> > > > > class FilterableContainer(BTreeContainer):
> > > > > 
> > > > >     implements(IFilterableContainer)
> > > > > 
> > > > >     def __init__(self):
> > > > >         super(FilterableContainer, self).__init__()
> > > > >         self._catalog = LocalCatalog()
> > > > >         self._catalog['attr1'] = FieldIndex(field_name='attr1')
> > > > > 
> > > > > where LocalCatalog is a subclass of Catalog that only indexes objects
> > > > > that belong to its parent.
> > > > > 
> > > > > The problem arises when I add my FieldIndex to my internal catalog. Some
> > > > > events are triggered and at the end I got this exception:
> > > > > 
> > > > >   File "/opt/Zope-3.2.1/lib/python/zope/app/keyreference/persistent.py",
> > > > > line 41, in __init__
> > > > >     raise zope.app.keyreference.interfaces.NotYet(object)
> > > > > NotYet: <zope.app.catalog.field.FieldIndex object at 0x2aaab3609b90>
> > > > > 
> > > > > 
> > > > > It happens because the key reference adaptor to Persistent thinks my
> > > > > FieldIndex object is already stored in the database, which is not the
> > > > > case.
> > > > > 
> > > > > Anybody knows how should I add an index to my catalog in the __init__
> > > > > method?
> > > > > 
> > > > > Thanks in advance
> > > > > 
> > > > > Lorenzo
> > > > > 
> > > > > _______________________________________________
> > > > > Zope3-users mailing list
> > > > > Zope3-users at zope.org
> > > > > http://mail.zope.org/mailman/listinfo/zope3-users
> > > > 
> > > > _______________________________________________
> > > > Zope3-users mailing list
> > > > Zope3-users at zope.org
> > > > http://mail.zope.org/mailman/listinfo/zope3-users
> > > 
> > 
> > _______________________________________________
> > Zope3-users mailing list
> > Zope3-users at zope.org
> > http://mail.zope.org/mailman/listinfo/zope3-users
> 



More information about the Zope3-users mailing list