Google Colabを使って業務自動化(RPA)を行っている際、「プログラムは『保存完了』と出すのに、Google Drive上のファイルが更新されていない(または消えている)」という謎現象に遭遇したことはありませんか?
特に、企業の 共有ドライブ(Shared Drive) で、10MBを超えるようなCSV/Excelファイルを扱う際にこの現象は顕著です。
今回は、この「幻の更新」問題を解決し、巨大ファイルでも100%確実に同期させるための 「OSコマンド強制書き込み術」 を紹介します。
🔴 発生した問題
Google ColabでPandasのデータフレームをCSVとして保存する際、通常は以下のように書きます。
# 一般的な書き方
df.to_csv('/content/drive/Shared drives/MyFolder/data.csv')
しかし、ファイルサイズが大きくなる(例:1万行超、10MB以上)と、以下のトラブルが始めました:
- Colab上ではエラーが出ず「保存完了」と表示される。
- しかし、Google Drive(ブラウザやPCのエクスプローラー)で見ると、昨日分が残ったまま。
- または、更新日時が一回しくなるが、中身は古いファイルに戻る(ロールバック現象)。
原因:Colabのマウントは「仮想的」ではない
Colabの /content/drive は、Linuxの標準的なファイルシステムではなく、FUSEという仕組みを使った「ネットワーク越しに見せているだけの仮想フォルダ」です。
Pythonの to_csv が完了しても、それは「Colabの一時メモリ(キャッシュ)に書き込まれただけ」で、Googleのサーバーへの送信(アップロード)はバックグラウンドで遅れて行われます。
巨大ファイルの場合、この遅延の転送が間に合わなかったり、通信がタイムアウトしたりして、結果として「書けたつもりで、実は消えている」**という事故が起きます。
✅ 解決策:Pythonではなく「OS(Linux)」に任せる
Pythonの open() や to_csv() ではなく、ColabのOSであるLinuxのコマンド(cp と sync)を使って、物理的にディスク同期を強制する方法が最も確実でした。
関数の開示:save_large_file_safely
以下が、今回作成した「絶対に飛ばさせない関数」です。
import os
import time
import subprocess
def save_large_file_safely(df, target_path):
"""
巨大ファイル(10MB超)を安全にGoogle Driveへ保存する関数
Pythonの保存ではなく、Linux (OS)のコマンドを使って確実に同期させる。
"""
# 1. まずColabのローカル(/content/配下)に一時保存
# ※ここはネットワーク同期がないので一瞬で終わる
temp_filename = "temp_upload.csv"
temp_path = f"/content/{temp_filename}"
print(f" [1/3] ローカル一時ファイル作成中...")
df.to_csv(temp_path, index=False, header=False, encoding='utf-8-sig')
# 2. Linuxの 'cp' コマンドでdriveへコピー
# ※shutil.copy よりもOSネイティブの cp の方が安定
print(f" [2/3] Driveへ書き込み中...")
cmd = f'cp -f "{temp_path}" "{target_path}"'
subprocess.call(cmd, shell=True)
# 3. (最重要)ディスク同期の強制(sync)
# メモリのバッファを全部ディスク(ネットワーク)に書き込ませる
print(f" [3/3] 同期フラッシュ中...")
subprocess.call('sync', shell=True)
# 4. 念のための待機(完璧に保存)
time.sleep(5)
# 5. 後片付け
if os.path.exists(temp_path):
os.remove(temp_path)
print(f" ✅ 完了!: {os.path.basename(target_path)}")
📌 ポイント解説
1. 一旦ローカルに仮出力:いきなりDrive(ネットワークドライブ)に to_csv すると、生成処理と転送処理が同時走って不安定になります。一旦ローカル(/content/)に完成品を作ることで、転送プロセスを単純な「ファイルコピー」にします。
2. cp -f コマンド:Pythonの shutil ライブラリよりも、OSレベルの cp コマンドの方が、ネットワークドライブに対する挙動がシンプルで強力です。
3. subprocess.call('sync', shell=True):これが最大の肝です。Linuxの sync コマンドは、「メモリに残っている書き込み待ちデータ」を全てディスク(ネットワーク)に送り込ませます。これにより、Colabが接続を切る前に、無理やりデータをGoogle Driveへ押し込みます。
📊 結果
この対策を入れると以前のすべての問題が解決できました。
| 項目 | 対応前(df.to_csv直書き) | 対応後(OSコマンド+sync) |
|---|---|---|
| 10MB以下のファイル | ○問題なし | ○問題なし |
| 1GB級のファイル | ×書き込まれない(日時が古い) | ○確実に書き込まれる |
| ファイルID | △新規作成すると変わってしまう | ○上書きするのでID保持(マクロ破損OK) |
まとめ
Google Colabで 「共有ドライブ」 や 「重いファイル」 を扱うときは、Python側のファイル操作を過信してはいけません。
「ローカルに作って、cpで送って、syncで押し込む」
この絶対守られば、RPAやマクロ連携での「データが古い!」というトラブルを完全に防ぐことができます。
