Custom field image to Featured Image

I put this together for you as a proof-of-concept. This class will migrate both attachment IDs and external image URLs into your featured images.

class Featured_Image_Migration{

    #Instantiate the migration by hitting /wp-admin/?migrate-post-meta=foobar
    protected $key = 'migrate-post-meta';
    protected $secret="foobar";

    #This is your legacy meta_key
    protected $meta_key = 'mainimg_medium';

    function __construct(){
        #Force this to run last so all includes are available
        add_action( 'admin_init', array($this, 'migrate_post_meta'), 999999 );
    }

    public function migrate_post_meta(){

        #Verify authorization and authentication
        if ( ! $this->verify_request() )
            return;

        global $wpdb;

        #Retrieve all featured image postmeta rows from prior theme
        $query = $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $this->meta_ );
        $results = $wpdb->get_results( $query );

        if ( $results ){
            foreach( $results as $result ){

                #Check if meta_value is a path
                if( preg_match( '/\//', $result->meta_value ) ){
                    $this->get_attachment_by_url( $result->meta_value, $result->post_id );
                    continue;
                }

                #Check if meta_value is an ID
                if( is_int( (int)$result->meta_value ) )

                    #Add a native WordPress featured image postmeta row
                    if( update_post_meta( $result->post_id, '_thumbnail_id', $result->meta_value ) )

                        #Send a message to the screen
                        show_message( "Post #$result->post_id - Featured image was set properly." );
            }
        }

        #Kill the admin process to see the message log
        exit;
    }

    private function verify_request(){

        #Only admins and those with the key/secret can run this in wp-admin
        if( current_user_can( 'manage_options' ) && isset( $_GET[$key] ) && $_GET[$key] === $secret )
            return true;

        return false;
    }

    private function get_attachment_by_url( $url, $post_id ){

        global $wpdb;

        #This is about as close as we can come to finding the attachment
        $query = $wpdb->prepare( "SELECT ID from $wpdb->posts WHERE guid = %s LIMIT 1", $url );
        $id = $wpdb->get_var( $query );

        if($id)
            #We found a match in the database!
            return $id;

        else{
            #If the URL is external, download the image into the post attachments
            add_action( 'add_attachment', array( $this, 'add_attachment') );
            $attachment = media_sideload_image( $url, $post_id );
            remove_action( 'add_attachment', array( $this, 'add_attachment') );
        }
    }

    public function add_attachment($id){

        #Get attachment post object
        $attachment = get_post( $id );

        #Add our newly sideloaded attachment as the featured image
        if( update_post_meta( $attachment->post_parent, '_thumbnail_id', $attachment->ID ) )
            show_message( "Post #$attachment->post_parent - Featured image was sideloaded and set properly." );
    }

}
new Featured_Image_Migration;

tech