[Grok-dev] Re: declaring catalog indexes

Philipp von Weitershausen philipp at weitershausen.de
Sun Apr 15 06:20:21 EDT 2007

Martijn Faassen wrote:
> The main drawback to this approach is that all indexes are set up 
> centrally. Of course you can write code to adjust the catalog later (and 
> have no setup_catalog), but are there patterns we can come up with to 
> make the creation of indexes more easy?
> Let's translate the above in another proposal:
> class App(grok.Application):
>     grok.local_utility(IntIds, provides=IIntIds)
>     grok.local_utility(Catalog, provides=ICatalog, name='my_catalog')

Why do you make the catalog a named utility? I've seen you like doing 
that (hurry.query's API always expects a name for the catalog, which 
makes for a bit of a confusing API if the catalog's an unnamed utility).

> class AIndex(grok.FieldIndex):
>    grok.catalog(App, 'my_catalog')
>    grok.attribute('a_attribute', ISomeInterface)

As somebody who knows the AttributeIndex API I would've expected 
something like this:

   class AIndex(grok.FieldIndex):
       grok.catalog(App, 'my_catalog')

       field_name = 'a_attribute'
       field_callable = False
       interface = ISomeInterface

> class BIndex(grok.TextIndex):
>    grok.catalog(App, 'my_catalog')
>    grok.attribute('b_attribute', ISomeInterface)

Somebody who's not entirely familiar with the ZODB and how we do 
indexing using the catalog probably won't think that this is 
straight-forward. It's also a lot of typing and repitition. I do 
understand and appreciate that it's pretty flexible because you can add 
additional indexes quite easily.

To reduce typing, the "grok.catalog(...)" line could be guessed if 
everything is in the same module and there's only one catalog (an 
unnamed utility) in the site.

Still, I wonder how many people (coming from Archetypes or other 
libraries that mangle a bit more information together) would expect to 
set the indexing flag directly in the model or in the schema. While this 
would mangle up things badly, I could think of a more compact spelling: 
write a data schema and then write an "index schema" next to it:

   class IMySchema(Interface):

       a_attribute = schema.Int()
       b_attribute = schema.Datetime()

       def c_method():

   class MySchemaIndexes(grok.Indexes):
       grok.schema(IMySchema) # this is actually the default

       a_attribute = grok.FieldIndex()
       b_attribute = grok.TextIndex(lexicon)  # additional parameters
       c_method = grok.SetIndex()   # field_callable is automatically
                                    # determined from the schema

What do you think?

> The indexes are grokked automatically and get created in the catalog 
> when 'App' is created using a subscriber. This allows an extension 
> modules to create new indexes in the core. Of course the app would still 
> need to be reinstalled to enable those indexes, but with some clever 
> event registration (IApplicationSetup event?) we might be able to handle 
> that quite nicely as well.

I think after setting up the catalog, we want to send an event 
(CatalogAddedEvent or something like that). Only that way we can ensure 
that indexes are set up *after* the catalog (Zope doesn't guarantee 
ordered execution of event handlers).

> One issue that this approach has is if indexes take other parameters 
> than the three I know about (attribute name, interface, boolean on 
> whether to call attribute or not). How do we pass them in? Does anyone 
> have experience with indexes that can use extra information?

The only indexes I've worked so far were attribute indexes. They take 
the three famous arguments but we could simply set them as attributes on 
the object as outlined above.

The TextIndex from zope.app.catalog.text also takes a lexicon as a 
fourth argument, though that too can be set as an attribute like the others.

http://worldcookery.com -- Professional Zope documentation and training

More information about the Grok-dev mailing list