Python · Google Drive ↔ OneDrive · Инженерное руководство с открытым исходным кодом

Как создать безопасный перенос между Google Drive и OneDrive на Python

Это руководство превращает обманчиво сложное копирование между облаками в чётко определённый процесс: составление перечня, предварительные проверки, промежуточное сохранение, хеширование, загрузка, повторное скачивание, сравнение, сохранение контрольной точки и лишь затем освобождение места на локальном диске.

Обновлено ; 22 мин чтения.

Краткий ответ

Для управляемой миграции FileArk автоматизирует этот процесс, не превращая ваш компьютер в узел передачи данных. Сервис протестирован на задачах миграции объёмом в несколько терабайт и, прежде чем сообщить об успехе, проверяет получение данных из источника, подтверждение загрузки провайдером и объект в целевом хранилище. Если вы хотите управлять процессом самостоятельно, приведённая ниже программа на Python под лицензией MIT выполняет перенос через ваш компьютер в консервативном режиме и никогда не удаляет исходные файлы.

Выберите модель работы, прежде чем выбирать код

Сервис прямой миграции между облачными хранилищами — практичный выбор, если библиотека велика, перенос должен выполняться без присмотра или данные не должны проходить через ноутбук. FileArk выполняет перенос онлайн, отслеживает ответы провайдеров, повторяет попытки при устранимых сбоях и показывает весь ход выполнения в одном интерфейсе. Перед тем как считать файл полностью перенесённым, система проверки выполняет три независимые проверки.

Локальный скрипт удобен, когда требуется полный контроль над приложениями OAuth, промежуточными дисками, журналами или правилами для папок назначения. Обратная сторона — операционная ответственность: компьютер должен оставаться включённым и подключённым к сети, сетевое соединение становится узким местом, учётные данные OAuth необходимо защищать, а на временном диске должно хватать места для активного пакета и проверочной копии.

Опубликованная здесь программа намеренно реализована консервативно. Она копирует данные из корня одного личного диска в новую папку назначения. В ней нет метода удаления; она не перезаписывает файлы при конфликтах, сохраняет надёжную контрольную точку после проверки и останавливается, если свободное место на локальном диске или в месте назначения становится меньше заданного резерва.

Конвейер переноса и границы распространения сбоев

  1. Составьте перечень дерева источника

    Адаптер источника рекурсивно обходит папки с учётом разбивки результатов провайдером на страницы, записывает идентификаторы, пути, типы и заявленные размеры, а также преобразует поддерживаемые файлы собственных форматов Google в переносимые форматы экспорта.

  2. Предварительно проверьте ёмкость целевого хранилища и локального диска

    Механизм сопоставляет объём ожидающих обработки данных с учётом настраиваемого резерва и квоту в месте назначения. Он также проверяет файловую систему промежуточного хранилища перед каждым пакетом и скачиванием каждого отдельного файла.

  3. Сохраните ограниченный пакет во временном хранилище

    Файлы обрабатываются пакетами с ограничениями как по общему объёму данных, так и по количеству файлов. Локальный диск используется только для текущего пакета, поэтому для большой библиотеки не требуется диск сопоставимого размера.

  4. Хеширование и загрузка

    После скачивания скрипт вычисляет локальный хеш SHA-256, проверяет известный размер исходного файла, создаёт папки в месте назначения и загружает данные возобновляемыми блоками, совместимыми с соответствующим провайдером.

  5. Проверка и сохранение контрольной точки

    В режиме по умолчанию новый объект повторно скачивается из целевого хранилища, после чего сравниваются хеши SHA-256. Только при совпадении файл записывается в контрольную точку JSON и удаляется из локальной промежуточной области.

Скачайте полную версию программы на Python под лицензией MIT

Скачиваемый файл представляет собой единую удобочитаемую точку входа Python. SDK провайдеров импортируются только при реальном переносе, поэтому демонстрационный режим и команды справки работают ещё до установки зависимостей и учётных данных. В отдельном файле требований зафиксированы минимальные версии поддерживаемых пакетов, а файл лицензии находится рядом с исходным кодом.

Перед использованием изучите код, протестируйте его на небольшой папке назначения и оставьте включённую по умолчанию проверку с повторным скачиванием для ценных данных. Ни один универсальный скрипт не способен воспроизвести все разрешения на общий доступ, ярлыки, метки хранения, правила общих дисков и политики арендатора.

Скачать программу переноса на Python
Прямая реализация на основе Google Drive API и Microsoft Graph с пакетной обработкой, контрольными точками, повторными попытками, резервами квоты и проверкой SHA-256 в месте назначения.
fileark-cloud-transfer.py · Python 3.10+ · лицензия MIT

Скачать список зависимостей Python
Небольшой список зависимостей для Google OAuth и Drive, аутентификации Microsoft, запросов Graph и повторных попыток.
requirements-fileark-cloud-transfer.txt · зависимости pip · обычный текст

Скачать лицензию MIT
Уведомление о разрешении, относящееся к обоим скриптам FileArk для переноса вручную.
LICENSE-fileark-cloud-transfer.txt · MIT · обычный текст

Ознакомьтесь с мерами безопасности до предоставления доступа к облачным хранилищам

Терминал с запущенным Python-скриптом FileArk для переноса файлов между облаками в демонстрационном режиме без подключения к сети
Встроенная демонстрация воспроизводит видимый оператору процесс без учётных данных и сетевых запросов. При реальном запуске выводятся те же сведения о ёмкости, пакетах, проверке, контрольной точке и состоянии удаления исходных файлов.

Сначала запустите демонстрационный режим. Он не обращается к сети и не записывает данные в облако. Последняя строка намеренно сформулирована однозначно: удалено ноль исходных файлов. Рабочий механизм выводит ту же последовательность событий в структурированные журналы и завершается с ненулевым кодом при обнаружении первого непроверенного файла.

Быстрая проверка без подключения к сети
chmod +x fileark-cloud-transfer.py
python3 fileark-cloud-transfer.py --demo
python3 fileark-cloud-transfer.py --help

Создайте клиенты OAuth без встраивания секретов

Для Google Drive создайте клиент OAuth типа «Настольное приложение» в проекте Google Cloud, включите Drive API, настройте экран согласия и скачайте клиентский файл JSON. Передайте путь к нему через параметр --google-client-secret или задайте переменную GOOGLE_OAUTH_CLIENT_SECRET_FILE. Скрипт запрашивает доступ к Google Drive, поскольку ему необходимо получать список файлов, скачивать их, создавать папки, загружать и проверять файлы.

Для OneDrive зарегистрируйте общедоступное клиентское приложение в Microsoft Entra ID, включите поток кода устройства, добавьте делегированное разрешение Files.ReadWrite и передайте идентификатор клиента приложения. Выберите common для личных и корпоративных учётных записей, organizations — для рабочих учётных записей или укажите идентификатор конкретного арендатора, если этого требует политика.

Токены кэшируются в локальных файлах, чтобы прерванную миграцию можно было возобновить без повторного входа. Считайте клиентский файл JSON и кэши токенов секретными данными: исключите их из системы контроля версий, ограничьте права доступа к ним в файловой системе, никогда не прикладывайте их к обращениям в службу поддержки и удалите после приёмки результатов миграции.

Установите зависимости в изолированной среде
python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements-fileark-cloud-transfer.txt

Запустите перенос из Google Drive в OneDrive или в обратном направлении

Все значения, связанные с идентификацией, задаёт оператор. В программе нет готовых идентификаторов клиента, секретов, арендаторов, токенов, удалённых учётных записей или учётных данных целевого хранилища. Первая команда выполняет вход в Google через браузер и в Microsoft с помощью кода устройства, а затем копирует файлы в новую папку OneDrive.

Чтобы выполнить перенос из OneDrive в Google Drive, поменяйте местами источник и назначение. Для каждой отдельной миграции используйте свой файл состояния и корневую папку назначения. Контрольная точка связывает воедино провайдера источника, провайдера назначения и корневую папку, а при несовпадении конфигурации программа отказывается возобновлять работу.

Из Google Drive в OneDrive пакетами по 8 GiB
export MICROSOFT_CLIENT_ID="your-public-client-id"
python fileark-cloud-transfer.py \
  --source google \
  --destination onedrive \
  --google-client-secret ./client_secret.json \
  --microsoft-tenant common \
  --destination-root "FileArk Manual Transfer 2026-07-25" \
  --batch-gib 8 \
  --batch-files 200 \
  --local-reserve-gib 15 \
  --destination-reserve-gib 10 \
  --verification redownload
Обратное направление: из OneDrive в Google Drive
python fileark-cloud-transfer.py \
  --source onedrive \
  --destination google \
  --microsoft-client-id "$MICROSOFT_CLIENT_ID" \
  --google-client-secret ./client_secret.json \
  --destination-root "OneDrive archive 2026-07-25" \
  --state-file ./onedrive-to-google-state.json \
  --verification redownload

Почему доступное место проверяется несколько раз

Результаты одной предварительной проверки могут устареть во время длительного переноса. Кто-то может загрузить другие файлы в целевое хранилище, экспортированный документ Google может оказаться больше, чем следует из метаданных исходного файла, а сторонние приложения могут занять место на локальном диске. Поэтому механизм проверяет общую ёмкость целевого хранилища перед запуском, доступное место в нём для каждого пакета и ещё раз после каждого локального скачивания, а также свободное место на локальном диске перед каждым этапом подготовки или созданием копии для проверки.

Значения резерва — это запас для стабильной работы, а не оценка объёма переноса. Задайте их с учётом обновлений операционной системы, задержек в учёте пространства провайдером и других пользователей той же облачной квоты. Если провайдер не сообщает конечный объём оставшейся квоты, скрипт выводит предупреждение и полагается на ограничения провайдера. Это менее надёжно, чем предварительная проверка по известному значению, поэтому требует активного мониторинга.

Инвариант квоты с безопасным отказом
def ensure_destination_capacity(quota, required, reserve):
    if quota.remaining is None:
        LOG.warning("Destination did not report a finite quota")
        return
    needed = required + reserve
    if quota.remaining < needed:
        raise RuntimeError(
            f"Destination is too small: {human_bytes(quota.remaining)} free, "
            f"{human_bytes(needed)} required including reserve."
        )

Ограничьте объём промежуточных данных по размеру и количеству файлов

Ограничение по объёму данных контролирует использование диска, а ограничение по числу файлов — нагрузку на API и файловую систему, когда источник содержит сотни тысяч небольших объектов. Файл, размер которого превышает лимит пакета, допускается как пакет из одного файла, поэтому резерв должен быть рассчитан на самый крупный отдельный объект.

По умолчанию размер фрагмента составляет 10 MiB. Это общее кратное для шага возобновляемой загрузки Google Drive, равного 256 KiB, и требования Microsoft Graph к последовательным фрагментам размером 320 KiB. Валидатор командной строки отклоняет несовместимые размеры фрагментов до аутентификации.

Планировщик пакетов с двумя ограничениями
def batches(files, max_bytes, max_files):
    batch, batch_size = [], 0
    for item in files:
        planned_size = max(item.size, 1)
        if batch and (
            len(batch) >= max_files
            or batch_size + planned_size > max_bytes
        ):
            yield batch
            batch, batch_size = [], 0
        batch.append(item)
        batch_size += planned_size
    if batch:
        yield batch

Обрабатывайте документы в нативных форматах Google путём преобразования

Документы, Таблицы, Презентации, Рисунки Google и проекты Apps Script не являются обычными доступными для скачивания потоками байтов. Адаптер Google экспортирует их соответственно в DOCX, XLSX, PPTX, PNG и JSON, добавляя к имени файла переносимое расширение. Скрипт обходит папки, но не загружает их как пустые объекты, если в них нет файлов.

При преобразовании могут измениться шрифты, формулы, комментарии, встроенные объекты, макет страниц и история совместной работы. Конечные точки экспорта Google также накладывают ограничения на формат и размер. Скрипт не пытается создать собственное представление неподдерживаемых нативных типов, а пропускает их с предупреждением. Проверьте вручную несколько типичных преобразованных файлов.

В эту версию не входят ярлыки, общие диски, файлы, к которым вам предоставили доступ, но которые не находятся в разделе «Мой диск», пакеты OneNote, метаданные хранения организации, история версий и списки управления доступом (ACL). Из-за этих ограничений копирование файлов нельзя называть полной миграцией арендатора.

Используйте полную проверку с повторным скачиванием из места назначения для точного сравнения байтов

Успешной загрузки на стороне провайдера необходимо, но недостаточно. После загрузки скрипт сначала сравнивает указанный в метаданных размер целевого объекта с размером промежуточного файла. Затем в режиме повторного скачивания, используемом по умолчанию, он скачивает целевой объект во временный файл в том же каталоге, вычисляет SHA-256 и сравнивает этот хеш с хешем промежуточной копии исходного файла.

Запись в контрольной точке создаётся, только если совпадают и размер, и хеш. В ней сохраняются идентификатор источника, заявленный источником размер, идентификатор назначения, путь назначения, фактическое число байтов, оба хеша и время завершения в UTC. Если путь источника, сохранённый в контрольной точке, позднее указывает на другой идентификатор или размер, скрипт останавливается, а не пропускает изменённые данные без предупреждения.

Повторное скачивание удваивает объём трафика чтения на стороне назначения и временно требует места как для промежуточного файла, так и для проверочной копии. Выбирайте режим проверки метаданных, только если понимаете связанные с этим издержки и располагаете независимым процессом проверки содержимого.

Проверка целевого файла побайтовым сравнением
destination.redownload(uploaded, verification_copy)
verification_hash = sha256_file(verification_copy)
if verification_hash != local_hash:
    raise RuntimeError(
        f"SHA-256 mismatch after destination re-download: {relative!r}."
    )

state["completed"][relative] = {
    "source_id": item.id,
    "destination_id": uploaded.id,
    "bytes": actual_size,
    "sha256": local_hash,
    "destination_sha256": verification_hash,
}

Возобновляйте работу, не принимая неопределённость за успех

Программа атомарно записывает состояние через временный файл с последующим переименованием. Проверенный элемент удаляется из локального промежуточного хранилища только после этой надёжной записи. При повторном запуске той же команды элементы, сохранённые в контрольной точке, пропускаются, а обработка продолжается с оставшихся путей.

Сбой может произойти после того, как провайдер примет загруженный файл, но до записи контрольной точки. Поскольку при конфликте выбрано поведение fail, следующий запуск остановится на уже существующем пути в целевом хранилище, а не перезапишет объект и не сообщит ошибочно об успехе. Проверьте объект и сравните его, а затем либо с осторожностью добавьте подтверждённую запись о восстановлении, либо перезапустите перенос с новым корневым каталогом в целевом хранилище.

При истечении срока действия OAuth, ограничении частоты запросов, временных ошибках сервера и прерывании передачи фрагментов выполняется ограниченное число повторных попыток. Ошибки аутентификации или постоянные проблемы с разрешениями останавливают программу. Сохраняйте журналы, контрольную точку и содержимое промежуточной области, пока не выясните причину сбоя.

Проведите полноценные приёмочные испытания

  • Начните с небольшой папки, содержащей пустые и большие файлы, глубоко вложенные пути, имена в Unicode и документы в нативных форматах Google.
  • Сначала запустите программу с параметром --dry-run и сравните общий объём файлов в перечне с данными в интерфейсе провайдера.
  • Во время обработки первого рабочего пакета независимо отслеживайте свободное место на локальном диске и квоту в месте назначения.
  • Не отключайте проверку с повторным скачиванием и сохраните контрольную точку в архиве вместе с документацией по миграции.
  • Откройте в целевом хранилище несколько типичных PDF-файлов, документов Office, изображений, видео, архивов и преобразованных документов в нативных форматах.
  • Сравните ожидаемое и фактическое количество папок и файлов, выясните причину пропуска или сбоя каждого элемента и проверьте доступ от имени второго пользователя.
  • Не изменяйте источник в течение заданного периода параллельного хранения. Этот скрипт никогда не удаляет из него данные.

Часто задаваемые вопросы

Удаляет ли Python-скрипт исходные файлы?

Нет. Удаление исходных файлов не реализовано. Механизм скачивает файлы из источника и записывает их в отдельный корневой каталог целевого хранилища; после успешной проверки удаляется только временная локальная копия из промежуточной области.

Можно ли переносить файлы в обоих направлениях?

Да. Укажите Google Drive или OneDrive в качестве источника, а другого провайдера — в качестве назначения. Для каждой миграции используйте отдельную контрольную точку и корневую папку назначения.

Сохраняются ли разрешения на общий доступ и история файлов?

Нет. Эта версия копирует текущее содержимое файлов и пути к папкам. Списки управления доступом (ACL), общедоступные ссылки, версии, комментарии, метки, политики хранения и метаданные организации требуют отдельной миграции и проверки.

Зачем повторно скачивать только что загруженные файлы?

Успешное принятие загруженного файла и размер в метаданных не доказывают, что из места назначения можно прочитать те же байты. В режиме повторного скачивания вычисляется SHA-256 содержимого в месте назначения, а контрольная точка создаётся только при точном совпадении.

Это официальный инструмент Google или Microsoft?

Нет. Это независимая эталонная реализация FileArk, опубликованная по лицензии MIT. Изучите её, протестируйте на некритичных данных и соблюдайте политики своего провайдера и организации.

Официальные источники, использованные в этом руководстве

Читать руководство