[Grok-dev] Migrating catalog indexes

Simon Jagoe azriphale at gmail.com
Thu Nov 26 18:24:24 EST 2009


2009/11/26 Kevin Teague <kevin at bud.ca>:
> If you've got an Indexes, such as:
>
> class MyIndexes(grok.Indexes):
>    grok.site(MyApp)
>    grok.context(gsc.haystack.interfaces.IContent)
>
>    created = grok.index.Field()
>
> And it gets grokked, then a catalog and a field index will be created.
> But then if you add a second field index:
>
> class MyIndexes(grok.Indexes):
>    grok.site(MyApp)
>    grok.context(gsc.haystack.interfaces.IContent)
>
>    created = grok.index.Field()
>    modified = grok.index.Field()
>
> This index doesn't get created. Soooo ... what's the best way to
> migrate a catalog when the indexes are updated after the initial
> creation. Anyone got any tips here?
> _______________________________________________
> Grok-dev mailing list
> Grok-dev at zope.org
> https://mail.zope.org/mailman/listinfo/grok-dev
>

Hi Kevin,

I may not be the best person to answer this as I was wondering the
same thing recently. I decided to poke around in the debug console to
see if I could come up with an answer.

I am using the debug prompt (./bin/app-debug) of the grok environment
for this experiment. I will write all of this with the assumption that
we have this grok.Indexes subclass:

class ResultIndexes(grok.Indexes):
    grok.site(App)
    grok.context(IResult)
    grok.name('my_catalog')
    name = index.Field()
    date = index.Field(attribute='get_date')
    is_verified = index.Field()

and we want to end up with this:

class ResultIndexes(grok.Indexes):
    grok.site(App)
    grok.context(IResult)
    grok.name('my_catalog')
    name = index.Field()
    date = index.Field(attribute='get_date')
    is_verified = index.Field()
    did_fall = index.Field()

Start the app debug prompt:

$ ./bin/app-debug
Welcome to the interactive debug prompt.
The 'root' variable contains the ZODB root folder.

The 'app' variable contains the Debugger, 'app.publish(path)'
simulates a request.

# Assuming you have an app called 'app' instantiated already:
>>> app = root[u'app']
>>> local_site_manager = app.getSiteManager()

# The name here is the value that was provided in the grok.name()
# directive on the class. I guess empty if you did not name your
# catalog.
>>> from zope.app.catalog.interfaces import ICatalog
>>> cat = local_site_manager.getUtility(ICatalog, name='my_catalog')

# The catalog is a container with keys of the fields you declared in
# your grok.Indexes subclass
>>> print [f for f in c.keys()]
[u'date', u'is_verified', u'name']

# To add a did_fall index, assuming did_fall is a schema.Bool declared
# on my IResult interface
>>> cat[u'did_fall'] = FieldIndex(field_name=u'did_fall')

# Not sure if this is required
>>> import transaction
>>> transaction.commit()

# Now update the index to include the new value
>>> cat.updateIndexes()

Then to test that the catalog had updated, I wrote a unit test (I
couldn't seem to use hurry.query in that debug prompt).

Adding a view with the following render method allowed me to test the
updated catalog. The result from this was [u'simon'], as expected. The
data to be indexed was present in the application before updating the
index.

    def render(self):
        from hurry.query.query import Query, Eq
        return str([r.__name__ for r in Query().searchResults(
                    Eq(('slalom_result_catalog', 'did_fall'), True))])

Hopefully this is coherent and useful, I wrote it up as I was
experimenting with this. Maybe somebody can throw in some more useful
comments (and perhaps how to turn this into a script that can be run
stand-alone would be useful too).

Regards,
Simon


More information about the Grok-dev mailing list