[Metakit] Find fails in hashed view but works in plain view or ordered view.

Thomas Mills Hinkle tmhinkle at gmail.com
Mon Oct 31 21:53:56 CET 2005


My confusion continues around find, locate, etc.

I have a generic method for fetching a single member from e.g. a table
with IDs. This method gets handed any view and then does the right
thing (with a different backend, it uses SQL or somesuch, with
metakit, it just returns view[view.find(**params)]). I now have a
mixture of plain views and ordered views.

I'm finding that my method fails with find. This strikes me as odd,
but you warned me to use locate() because this would happen.

So I'm using locate, which usually works. Occasionally, though, locate
and/or find both fail even though select works.

The odd thing is that the place where only select works is on the
surface identical to the places where locate() does the trick.
Specifically -- I have a table for keeping track of values that
autoincrement (a workaround to metakit's lack of autoincrement
functionality). This table is of the form

increment_view[view:s,field:s,n:i]

Where view and field reference a field to be incremented and n
references the current top number.

metakit.dumping the view reveals the following structure:

 view          field  n
 ------------  -----  ---
 category      id       1
 cuisine       id       1
 foodgroup     id      23
 inggroup      id       1
 ingkey        id     412
 item          id     460
 nutrition     ndbno    1
 recipe        id       1
 shopcategory  id       1
 source        id       1
 unit          id       1
 word          id     446
 ------------  -----  ---
 Total: 12 rows

Using locate(view=view,field=field) works for all fields and views
except shopcategory, for which it fails. For shopcategory,
select(view=view,field=field)[0] returns the row that locate() fails
to reference.

This all strikes me as quite mysterious. Any light that could be shed
on the differences between find, locate and select would be much
appreciated.

Tom

p.s. Here is the rather ugly method I'm using currently to work around
the failures of one or the other method to work. It would be great if
I could somehow detect which method will work for a given view and
just do the right thing.

Views are called tables here in parallel with other code for e.g. SQL backends.

    def fetch_one (self, table, *args, **kwargs):
        # Method 1: locate
        print 'fetch_one:',table.structure(),args,kwargs
        indx,cnt=table.locate(*args,**kwargs)
        if cnt:
            print 'Locate works!'
            return table[indx]
        else:
            # method 2: find
            new_indx = table.find(*args,**kwargs)
            if new_indx>-1:
                print 'Locate missed me, but find worked'
                return table[new_indx]
            # method 3: select
            rows = table.select(*args,**kwargs)
            if rows:
                print "Find and locate missed me, but select worked."
                print "Find -> -1, Locate ->",indx,cnt
                metakit.dump(table)
                return rows[0]
        print 'Return None'


More information about the Metakit mailing list