def convert(
    src: str,
    dst: str,
    dst_creds: Optional[Dict[str, str]] = None,
    token: Optional[str] = None,
) -> None:
    """
    Copies the v3 dataset at src into a new dataset in the new v4 format.
    """

    def commit_data(dataset, message="Committing data"):
        dataset.commit()

    def get_raw_columns(source):
        return [
            col.name
            for col in source.schema.columns
            if not col.dtype.is_link and col.dtype.kind in {
                deeplake.types.TypeKind.Image,
                deeplake.types.TypeKind.SegmentMask,
                deeplake.types.TypeKind.Medical,
            }
        ]

    def transfer_non_link_data(source, dest):
        dl = deeplake._deeplake._Prefetcher(source, raw_columns=set(get_raw_columns(source)))
        for counter, batch in enumerate(progress_bar(dl), start=1):
            dest.append(batch)
            if counter % 100 == 0:
                commit_data(dest)
        commit_data(dest, "Final commit of non-link data")

    def transfer_with_links(source, dest, links, column_names):
        iterable_cols = [col for col in column_names if col not in links]
        link_sample_info = {link: source[link]._links_info() for link in links}
        dest.set_creds_key(link_sample_info[links[0]]["key"])
        quoted_cols = ['"' + col + '"' for col in iterable_cols]
        joined_cols = ",".join(quoted_cols)
        pref_ds = source.query(f"SELECT {joined_cols}")
        dl = deeplake._deeplake._Prefetcher(pref_ds, raw_columns=set(get_raw_columns(source)))

        for counter, batch in enumerate(progress_bar(dl), start=1):
            batch_size = len(batch[iterable_cols[0]])
            for link in links:
                link_data = link_sample_info[link]["data"]
                start_index = (counter - 1) * batch_size
                end_index = min((counter) * batch_size, len(link_data))
                batch[link] = link_data[start_index:end_index]

            dest.append(batch)
            if counter % 100 == 0:
                commit_data(dest)
        commit_data(dest, "Final commit of linked data")

    source_ds = deeplake.query(f'SELECT * FROM "{src}"', token=token)
    dest_ds = deeplake.like(source_ds, dst, dst_creds, token=token)
    commit_data(dest_ds, "Created dataset")

    column_names = [col.name for col in source_ds.schema.columns]
    links = [
        col.name
        for col in source_ds.schema.columns
        if source_ds.schema[col.name].dtype.is_link
    ]
    print(f"Transferring {len(source_ds)} rows to {dst}...")
    if not links:
        transfer_non_link_data(source_ds, dest_ds)
    else:
        transfer_with_links(source_ds, dest_ds, links, column_names)

    for column in column_names:
        meta = dict(source_ds[column].metadata)
        if meta:
            for key, value in meta.items():
                dest_ds[column].metadata[key] = value

    commit_data(dest_ds, "Final commit of metadata")
    print(f"Data transfer to {dst} complete.")

    Copies the v3 dataset at src into a new dataset in the new v4 format.
    
python/deeplake/__init__.py