docs: def read_names(rows, source_id=1):
      """Return an iterator of rows ready to insert into table
      "names". Adds columns "is_primary" (identifying the primary name
      for each tax_id with a vaule of 1) and "is_classified" (always None).
  
      * rows - iterator of lists (eg, output from read_archive or read_dmp)
      * unclassified_regex - a compiled re matching "unclassified" names
  
      From the NCBI docs:
  
      Taxonomy names file (names.dmp):
          tax_id -- the id of node associated with this name
          name_txt -- name itself
          unique name -- the unique variant of this name if name not unique
          name class -- (synonym, common name, ...)
  
      """
  
      ncbi_keys = ['tax_id', 'tax_name', 'unique_name', 'name_class']
      extra_keys = ['source_id', 'is_primary', 'is_classified']
  
      # is_classified applies to species only; we will set this value
      # later
      is_classified = None
  
      tax_id = ncbi_keys.index('tax_id')
      tax_name = ncbi_keys.index('tax_name')
      unique_name = ncbi_keys.index('unique_name')
      name_class = ncbi_keys.index('name_class')
  
      yield ncbi_keys + extra_keys
  
      for tid, grp in itertools.groupby(rows, itemgetter(tax_id)):
          # confirm that each tax_id has exactly one scientific name
          num_primary = 0
          for r in grp:
              is_primary = r[name_class] == 'scientific name'
              # fix primary key uniqueness violation
              if r[unique_name]:
                  r[tax_name] = r[unique_name]
              num_primary += is_primary
              yield (r + [source_id, is_primary, is_classified])
  
          assert num_primary == 1