Quote:
Originally Posted by kiwidude
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)