docs: def create_index(self, attr, unique=False, accept_none=False):
          """Create a new index on a given attribute.
             If C{unique} is True and records are found in the table with duplicate
             attribute values, the index is deleted and C{KeyError} is raised.
  
             If the table already has an index on the given attribute, then
             ValueError is raised.
             @param attr: the attribute to be used for indexed access and joins
             @type attr: string
             @param unique: flag indicating whether the indexed field values are 
                 expected to be unique across table entries
             @type unique: boolean
             @param accept_none: flag indicating whether None is an acceptable
                 unique key value for this attribute (always True for non-unique
                 indexes, default=False for unique indexes)
             @type accept_none: boolean
          """
          if attr in self._indexes:
              raise ValueError('index %r already defined for table' % attr)
  
          if unique:
              self._indexes[attr] = _UniqueObjIndex(attr, accept_none)
              self._uniqueIndexes = [ind for ind in self._indexes.values() if ind.is_unique]
          else:
              self._indexes[attr] = _ObjIndex(attr)
              accept_none = True
          ind = self._indexes[attr]
          try:
              for obj in self.obs:
                  obval = getattr(obj, attr, None)
                  if obval is not None or accept_none:
                      ind[obval] = obj
                  else:
                      raise KeyError("None is not an allowed key")
              return self
                      
          except KeyError:
              del self._indexes[attr]
              self._uniqueIndexes = [ind for ind in self._indexes.values() if ind.is_unique]
              raise