docs: def export(self, sql_client, merge_rule='skip', coerce=False):
  
          '''
              a method to export all the records in table to another table
  
          :param sql_client: class object with sql client methods
          :param merge_rule: string with name of rule to adopt for pre-existing records
          :param coerce: boolean to enable migration even if table schemas don't match
          :return: string with exit message
  
          NOTE:   available merge rules include: overwrite, skip and upsert
          '''
  
          title = '%s.export' % self.__class__.__name__
  
      # validate sql client
          method_list = [ 'list', 'create', 'read', 'update', 'delete', 'remove', 'export', 'exists', '_construct_inserts', '_parse_columns', '_compare_columns', 'table', 'session', 'table_name', 'database_name' ]
          for method in method_list:
              if getattr(sql_client, method, None) == None:
                  from labpack.parsing.grammar import join_words
                  raise ValueError('%s(sql_client=...) must be a client object with %s methods.' % (title, join_words(method_list)))
      
      # verbosity
          export_name = self.table_name
          import_name = sql_client.table_name
          print('Migrating %s table in %s database to %s table in %s database' % (export_name, self.database_name, import_name, sql_client.database_name), end='', flush=True)
  
      # determine differences between tables
          export_columns = self._parse_columns()
          import_columns = sql_client._parse_columns()
          add_columns, remove_columns, rename_columns, retype_columns, resize_columns = self._compare_columns(import_columns, export_columns)
          if remove_columns or retype_columns or resize_columns:
              if not coerce:
                  raise ValueError("Migration from %s to %s prevented because schemas don't match and data could be lost." % (export_name, import_name))
  
      # define upsert reconstructor
          def _reconstruct_upsert(update_kwargs):
              record_details = {}
              current_details = record_details
              for key, value in update_kwargs.items():
                  record_key = key
                  record_value = value
                  record_segments = record_key.split('.')
                  for i in range(len(record_segments)):
                      segment = record_segments[i]
                      if i + 1 < len(record_segments):
                          if segment not in record_details.keys():
                              current_details[segment] = {}
                          current_details = current_details[segment]
                      else:
                          if isinstance(record_value, bytes):
                              current_details[segment] = pickle.loads(record_value)
                          else:
                              current_details[segment] = record_value
                  current_details = record_details
              return record_details
  
      # migrate records from old to new
          list_statement = self.table.select()
          count = 0
          added = 0
          skipped = 0
          upserted = 0
          overwritten = 0
          for record in self.session.execute(list_statement).fetchall():
              record_details = self._reconstruct_record(record)
              primary_key = record_details['id']
              if not sql_client.exists(primary_key):
                  create_kwargs = self._construct_inserts(record, import_columns, rename_columns, retype_columns, resize_columns)
                  insert_statement = sql_client.table.insert().values(**create_kwargs)
                  sql_client.session.execute(insert_statement)
                  added += 1
              elif merge_rule == 'overwrite':
                  sql_client.delete(primary_key)
                  create_kwargs = self._construct_inserts(record, import_columns, rename_columns, retype_columns, resize_columns)
                  insert_statement = sql_client.table.insert().values(**create_kwargs)
                  sql_client.session.execute(insert_statement)
                  overwritten += 1
              elif merge_rule == 'skip':
                  skipped += 1
              elif merge_rule == 'upsert':
                  update_kwargs = self._construct_inserts(record, import_columns, rename_columns, retype_columns, resize_columns)
                  update_details = _reconstruct_upsert(update_kwargs)
                  sql_client.update(update_details)
                  upserted += 1
              count = added + overwritten + skipped + upserted
              if not count % 10:
                  print('.', end='', flush=True)
  
      # handle verbosity
          print(' done.')
  
      # report outcome
          plural = ''
          skip_insert = ''
          overwrite_insert = ''
          upsert_insert = ''
          if added != 1:
              plural = 's'
          if skipped > 0:
              skip_plural = ''
              if skipped > 1:
                  skip_plural = 's'
              skip_insert = ' %s record%s skipped to avoid overwrite.' % (str(skipped), skip_plural)
          if overwritten > 0:
              overwrite_plural = ''
              if overwritten > 1:
                  overwrite_plural = 's'
              overwrite_insert = ' %s record%s overwritten.' % (str(overwritten), overwrite_plural)
          if upserted > 0:
              upsert_plural = ''
              if upserted > 1:
                  upsert_plural = 's'
              upsert_insert = ' %s record%s upserted.' % (str(upserted), upsert_plural)
          exit_msg = '%s record%s added to %s.%s%s%s' % (str(added), plural, import_name, skip_insert, overwrite_insert, upsert_insert)
          print(exit_msg)
  
          return count