View Single Post
Old 03-12-2011, 03:32 AM   #11
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,742
Karma: 6997045
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by kiwidude View Post
Charles, I am getting a KeyError: '#extra#' error when I try to call set_metadata when I use that set_all_user_metadata call above. I take it there is another special trick required to set that 'extra' data?
set_all_user_metadata sets the metadata. It does not set the values, because it doesn't know what they should be. It is up to you to do that.
Quote:
Code:
...snip...
db.import_book(mi, [])
print 'imported book:', mi.id
You are adding new books to the DB? In that case you need to supply all the information you want to set. Probably using set_all_user_metadata is inappropriate.

The only reason to put user (custom) metadata into a Metadata instance is if you are going to put a value in there. If you have a value for a particular column, then set the metadata for that column, then set the value for that column. Something like
Code:
        meta = db.metadata_for_field(key)
        mi.set_user_metadata(key, meta)
        mi.set(key, val=whatever_it_is, extra=whatever_it_is)
It is permissable to not have metadata for a custom column in mi when calling set_metadata. Such columns will have their db default value, which IIRC is always None (might be something else for dates).

The underlying issue here is that Metadata instances can come from a variety of places, most of which are not the db. OPF files are a common example, It is normal that there isn't any strict correspondence between the columns in the library and the information in the Metadata instance. Get_metadata gives you what is in the current library, which may have nothing to do with what will be in some other library -- think copying between libraries.

The consequence is that the code must ensure that the metadata is appropriate for its purpose. If you need to set a particular custom column, then you must add it to the record and set its value. Unless you are sure of the source you shouldn't trust the metadata for a given column, because #read might be bool in library 1 but enumeration in library 2. This is why one sees column and type guards in set_metadata:
Code:
        for key in user_mi.iterkeys():
            if key in self.field_metadata and \
                    user_mi[key]['datatype'] == self.field_metadata[key]['datatype']:
                doit(self.set_custom, id,
                     val=mi.get(key),
                     extra=mi.get_extra(key),
                     label=user_mi[key]['label'], commit=False)
chaley is offline   Reply With Quote