月曜日, 4月 28, 2025
Google search engine
ホームニューステックニュースGoogle Drive APIでファイルアップロード時に「storage quota exceeded」エラーが出た話と対処方法 #Python

Google Drive APIでファイルアップロード時に「storage quota exceeded」エラーが出た話と対処方法 #Python



Google Drive APIでファイルアップロード時に「storage quota exceeded」エラーが出た話と対処方法 #Python

先日、Python スクリプトから Google Drive API を利用してファイルをアップロードしようとした際に、以下のように "The user's Drive storage quota has been exceeded." というエラーが発生しました。

googleapiclient.errors.HttpError: 

エラーメッセージに記載されている通り、Google Drive のストレージの割り当て上限に達してしまったことが原因でした。

普段は Google Drive の使用量をあまり意識していませんでしたが、API経由でファイルをアップロードする際に上限に達した場合の処理を備忘録として記事化しておきます。

現在のストレージ使用量を確認

まず現状を把握するため、Google Drive API を使って現在のストレージ使用量を確認しました。
about().get() メソッドを利用すると、ストレージに関する情報を取得できます。

以下が実行した Python コードです。

import sys
import os
from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build

# サービスアカウントキーのファイルパス ※実際のパスに置き換えてください
SERVICE_ACCOUNT_FILE = 'path/to/your/service_account.json'
SCOPES = ['https://www.googleapis.com/auth/drive']

# 認証情報を作成
creds = Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
drive_service = build('drive', 'v3', credentials=creds)

# aboutリソースから storageQuota フィールドを取得
try:
    about = drive_service.about().get(fields="storageQuota").execute()
    print(about)
except Exception as e:
    print(f"ストレージ情報の取得中にエラーが発生しました: {e}")

実行例:

{
  "storageQuota": {
    "limit": "16106127360",
    "usage": "16084258429",
    "usageInDrive": "16084258429",
    "usageInDriveTrash": "0"
  }
}
  • limit: ストレージ容量の上限(バイト単位)
  • usage: 現在の使用量(バイト単位)

無料のGoogleアカウントに紐づくDriveでは通常15GiBのストレージ制限があり、サービスアカウント経由でもこの制限が適用されるようです。今回の結果からも、使用量がほぼ上限に達していることが確認できました。

自分が所有するファイル一覧をリストアップ

ストレージ状況を把握するために、「自分がオーナーのファイル一覧」をリストアップするスクリプトも作成しました。
不要ファイルの整理や、容量を圧迫しているファイルの特定に役立ちます。

以下のPythonコードで、自分が所有しているすべてのファイルを取得して表示しました。

from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build

# サービスアカウントキーのファイルパス
SERVICE_ACCOUNT_FILE = 'path/to/your/service_account.json'
SCOPES = ['https://www.googleapis.com/auth/drive']

# 認証情報を作成
creds = Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
drive_service = build('drive', 'v3', credentials=creds)

# 自分が所有しているすべてのファイルを取得
query = "'me' in owners and trashed = false"
page_token = None

print("自分が所有するファイル一覧:")

while True:
    response = drive_service.files().list(
        q=query,
        fields="nextPageToken, files(id, name, mimeType, size, createdTime)",
        pageSize=100,
        pageToken=page_token
    ).execute()

    for file in response.get('files', []):
        print(f"- {file['name']} (ID: {file['id']}, MIME: {file['mimeType']}, Size: {file.get('size', 'N/A')} bytes)")

    page_token = response.get('nextPageToken', None)
    if page_token is None:
        break

実行例:

自分が所有するファイル一覧:
- sample.txt (ID: xxxxxxxxxx, MIME: text/plain, Size: 68 bytes)
- hoge.zip (ID: yyyyyyyyyy, MIME: application/x-zip-compressed, Size: 55884639 bytes)
- fuge.zip (ID: zzzzzzzzzz, MIME: application/x-zip-compressed, Size: 830795032 bytes)

...

古い ZIPファイルを削除して空き容量を確保

ストレージ容量を圧迫している原因を探ったところ、過去にアップロードしたZIPファイルが大量に溜まっていることが原因だったので、Google Drive API を利用して、60日よりも前にアップロードしたZIPファイルを検索し削除する Python スクリプトを作成しました。

from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build
from datetime import datetime, timedelta, timezone
import time

# サービスアカウントキーのファイルパス
SERVICE_ACCOUNT_FILE = 'path/to/your/service_account.json'
SCOPES = ['https://www.googleapis.com/auth/drive']

# 認証情報を作成
creds = Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
drive_service = build('drive', 'v3', credentials=creds)

# サービスアカウントのメールアドレス(オーナー識別に使用)
owner_email = creds.service_account_email

# --- 削除条件設定 ---
DAYS_THRESHOLD = 60  # 60日より古いファイルを削除
TARGET_EXTENSIONS = ('.zip', '.tar.gz')  # 対象拡張子(小文字)
# --------------------

threshold_date = datetime.now(timezone.utc) - timedelta(days=DAYS_THRESHOLD)
query = f"'{owner_email}' in owners and trashed = false"

page_token = None
deleted_count = 0
processed_count = 0

print(f"削除処理を開始します。作成日時が {threshold_date.strftime('%Y-%m-%d %H:%M:%S %Z')} より前の {', '.join(TARGET_EXTENSIONS)} ファイルを削除します。")

while True:
    try:
        response = drive_service.files().list(
            q=query,
            fields="nextPageToken, files(id, name, createdTime, size)",
            pageSize=100,
            pageToken=page_token
        ).execute()
    except Exception as e:
        print(f"nファイルリストの取得中にエラーが発生しました: {e}")
        print("60秒待機して再試行します...")
        time.sleep(60)
        continue

    files = response.get('files', [])
    if not files:
        print("n対象ファイルが見つかりませんでした。")
        break

    print(f"n{len(files)} 件のファイルを取得しました。削除対象か確認します...")

    for file in files:
        processed_count += 1
        name = file.get('name', 'N/A')
        file_id = file.get('id')
        created_time_str = file.get('createdTime')

        if not name or not file_id or not created_time_str:
            print(f" - [スキップ] ファイル情報が不完全です: ID={file_id}, Name={name}")
            continue

        if not name.lower().endswith(TARGET_EXTENSIONS):
            continue

        try:
            created_time = datetime.fromisoformat(created_time_str.replace('Z', '+00:00'))
        except ValueError:
            print(f" - [スキップ] 作成日時の形式が無効です: {name} ({created_time_str})")
            continue

        if created_time  threshold_date:
            file_size_mb = int(file.get('size', 0)) / (1024 * 1024)
            print(f" - [削除対象] {name} (作成日: {created_time.strftime('%Y-%m-%d')}, サイズ: {file_size_mb:.2f} MB, ID: {file_id})")
            try:
                drive_service.files().delete(fileId=file_id).execute()
                deleted_count += 1
                print(f"   -> 削除成功")
                time.sleep(0.5)
            except Exception as e:
                print(f"   -> !!! 削除失敗: {name} - {e}")
                # 必要に応じてリトライなどのエラーハンドリングを追加してください

    page_token = response.get('nextPageToken')
    if page_token is None:
        print("n全てのファイルの確認が完了しました。")
        break

print(f"n--- 処理結果 ---")
print(f"確認したファイル数: {processed_count}")
print(f"削除したファイル数: {deleted_count}")
print(f"-----------------")

同じようなエラーに遭遇した方の参考になれば幸いです



フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -
Google search engine

Most Popular

Recent Comments