def migrate_database_if_necessary(
    destination=None, verbose=False, config=None
):
    """Migrates the database to the specified revision, if necessary.

    If ``fiftyone.config.database_admin`` is ``False`` and no ``destination``
    is provided, the database will only be migrated if its current version is
    not compatible with the client's version.

    Args:
        destination (None): the destination revision. By default, the
            ``fiftyone`` client version is used
        verbose (False): whether to log incremental migrations that are run
        config (None): an optional :class:`DatabaseConfigDocument`. By default,
            DB config is pulled from the database.
    """
    if _migrations_disabled():
        return

    if config is None:
        config = foo.get_db_config()

    head = config.version

    default_destination = destination is None

    if default_destination:
        if _can_skip_migration(head):
            return

        destination = foc.VERSION

    if head == destination:
        return

    if not fo.config.database_admin:
        if default_destination:
            if foc.COMPATIBLE_VERSIONS:
                compat_str = " (compatibility %s)" % foc.COMPATIBLE_VERSIONS
            else:
                compat_str = ""

            raise EnvironmentError(
                "Cannot connect to database v%s with client v%s%s. "
                "See https://docs.voxel51.com/user_guide/config.html#database-migrations "
                "for more information" % (head, destination, compat_str)
            )
        else:
            raise EnvironmentError(
                "Cannot migrate database from v%s to v%s when database_admin=%s. "
                "See https://docs.voxel51.com/user_guide/config.html#database-migrations "
                "for more information"
                % (head, destination, fo.config.database_admin)
            )

    if _database_exists():
        runner = MigrationRunner(head, destination)
        if runner.has_admin_revisions:
            logger.info("Migrating database to v%s", destination)
            runner.run_admin(verbose=verbose)

    config.version = destination
    config.save()
Migrates the database to the specified revision, if necessary.

    If ``fiftyone.config.database_admin`` is ``False`` and no ``destination``
    is provided, the database will only be migrated if its current version is
    not compatible with the client's version.

    Args:
        destination (None): the destination revision. By default, the
            ``fiftyone`` client version is used
        verbose (False): whether to log incremental migrations that are run
        config (None): an optional :class:`DatabaseConfigDocument`. By default,
            DB config is pulled from the database.
    
fiftyone/migrations/runner.py