Log in |
How To: Use the Catalog-Class out of ZopeAbstractBy 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 exampleConsider 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!
|