You are not logged in Log in Join
You are here: Home » Members » kelcmab3 » How To: Use the Catalog-Class out of Zope

Log in
Name

Password

 

How To: Use the Catalog-Class out of Zope

How To: Use Catalog Classes out of Zope

Abstract

By nature I am very curiuos and in the first days, I use Zope I want to know how to use the Catalog-Class outside of Zope. I kneeded an hour or two to let it work. I didn't found anything in the documentation so I think someone else could use this information.

The Catalog Class in a Code example

Consider the following code:

import sys
sys.path.append('/opt/Zope/lib/python')
import ZODB
import Persistence
from Persistence import Persistent
from ZODB.FileStorage import FileStorage
from Products.ZCatalog.Catalog import Catalog

### create some classes to be persistent
class Nobody( Persistent ):
    def identify( self ):
        print "I am Nobody!"
        
class Person( Persistent ):
    def __init__( self, first, name, email, friend=Nobody() ):
        self.first = first
        self.name  = name
        self.email = email
        self.friend= friend
    def identify( self ):
        print "I am " + self.first + " " + self.name
        print "and my Email is " + self.email

### OK, the ZODB-API together with a Catalog-Class
class Application:
    def __init__( self, file='db.fs' ):
        self.file= file
        self.db  = ZODB.DB( FileStorage( file ) )
        self.co  = self.db.open()
        self.root= self.co.root()
        if self.root.has_key( 'cat' ):
            self.cat= self.root['cat']
        else:
            self.cat        = Catalog()
### This is, how I get it to work
            self.cat.aq_parent= self.root
            
	    self.root['cat']= self.cat
           
### Add indexes to the Catalog-Class
### The names must match the fields of the Person-Class!
            self.cat.addIndex('first','FieldIndex' )
            self.cat.addIndex('name' ,'FieldIndex' )
            self.cat.addIndex('email','FieldIndex' )
            get_transaction().commit()
            
    def storePerson( self, person ):
        uid= id( person )
        print "stored as " + str( uid )
        self.root[uid]= person

### Let the Catalog know from this object
        self.cat.catalogObject( person, uid )
        get_transaction().commit()
        
    def searchPerson( self, **kw ):
        r= self.cat.searchResults( kw )
        paths= self.cat.paths
        root = self.root
        k= []
        for i in r:
            id= i.data_record_id_
            k.append( root[paths[id]] )
        return k
The hack is the line "self.cat.aq_parent=self.root". Without this line I'm running mad because whenever the Catalog founds a matching class, an Exception occurs that the catalog-class has no attribute called aq_parent. Setting it to "None" doesnt work, so I set it to self.root. I really dont now if this is the right way, but it seems to work! If someone knows it better, let me know!
Here is the code-example on how to use the classes above:
### test1.py
from defs import Application, Person
a= Application()
p1= Person( 'marian','kelc','marian.kelc@ruhr-uni-bochum.de' )
p2= Person( 'tanja', 'kreierhoff','tanja.kreierhoff@web.de', p1 )
p1.friend= p2
a.storePerson( p1 )
a.storePerson( p2 )

### test2.py
from defs import Application, Person
a= Application()

### perform searches with keyword-arguments
ids= a.searchPerson( name='kelc' )

for i in ids:
    i.identify()
    print "Friend is:"
    i.friend.identify()
    i.friend.friend.identify()
    print str( id( i ) )
    print str( id( i.friend.friend ) )
Hm, the last two lines show you, that the ZODB is really aware on circular object references! :-)

I hope, this could be helpful for someone!