【问题标题】:Upload large file not working - Google Drive Python API上传大文件不起作用 - Google Drive Python API
【发布时间】:2017-09-17 12:42:49
【问题描述】:

此脚本适用于小文件,但不适用于我尝试上传大文件 (250MB) 时。当我手动将同一个大文件上传到 GD 时,只需不到 10 秒,所以我认为我的连接不是问题。

上传.py

from __future__ import print_function
import os
import sys

from apiclient.http import MediaFileUpload
from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

SCOPES = 'https://www.googleapis.com/auth/drive.file'
store = file.Storage(r'C:\Users\lucas.rezende\.credentials\storage.json')
creds = store.get()

if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets(r'C:\Users\lucas.rezende\.credentials\client_secret.json', scope=SCOPES)
    creds = tools.run_flow(flow, store, flags) if flags else tools.run(flow, store)
DRIVE = build('drive', 'v3', http=creds.authorize(Http()))

FILES = (
    ('OfertasMensais_20170418_n.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'),
)

for filename, mimeType in FILES:

    media_body = MediaFileUpload(filename, chunksize=1024*256, resumable = True)

    folder_id = '0000'
    metadata = {'name': filename, 'parents': [folder_id]}

    if mimeType:
        metadata['mimeType'] = mimeType
    res = DRIVE.files().create(body=metadata, media_body=filename).execute()

    if res:
        print('Uploaded "%s" (%s)' % (filename, res['mimeType']))

当我运行python uploadfile.py cmd 时,屏幕永远保持这种状态:

有人可以帮助发现如何进行这项工作吗?我不是专业的程序员,为了完成这项工作,我被困了将近两个小时。

【问题讨论】:

标签: python python-3.x api google-drive-api


【解决方案1】:

按照分块范式,您需要专门调用next_chunk() 以继续上传。看这里:https://developers.google.com/api-client-library/python/guide/media_upload#resumable-media-chunked-upload

for filename, mimeType in FILES:
    media_body = MediaFileUpload(filename, chunksize=1024*256, resumable = True) 

    if mimeType:
        metadata['mimeType'] = mimeType

    req = DRIVE.files().insert(body=metadata, media_body=filename)
    res = None
    while res is None:
        status, res = req.next_chunk()
        if status :
            print('Uploading %d%% "%s" (%s)' % (status.progress(), filename, res['mimeType']))
    print("Upload Complete!")

【讨论】:

  • 我将我的代码更新为这个,但它似乎缺少一些导入。我有一个NameError: name 'request' is not ndefined。我目前支持它。
  • 根据我在您发送的链接上看到的内容,我还可以从 MediaFileUpload 中删除单个请求中的 chunksize=1024*256...
  • @LucasRezende 刚刚编辑它reqrequest。你也可以这样做!您还需要删除 resumeable 标志。
  • 我看到您使用insert 方法发布了req,但在API v3 中不再使用此方法。它使用create().execute(),当我这样说时,我得到一个错误,说req 没有​​next_chunk() 方法。有什么建议吗?
  • 我的 2c 是当任何库开始妨碍时,停止使用它。直接使用 REST API,格式良好且易于使用。这样,您还可以使用 v2 和 v3 的组合,同时解决 v3 中的不足。
【解决方案2】:

v3 的解决方案是使用分块方法,但使用 create() 函数而不是 insert()

            res = None
            media_body = MediaFileUpload(filename, chunksize=1024*256, resumable = True)

            drive_request = self.drive.files().create(body=metadata,media_body=media_body)
            while res is None:
                status, res = drive_request.next_chunk()

【讨论】:

  • 我认为 sintax 是错误的。你应该使用 DRIVE 而不是 drive_request 来调用 next_chunk() 方法,对吧?
  • @EduardoFernandes 是的,你是对的,似乎我在粘贴后编辑了代码以匹配 OP 的内容,但我错过了在这两个地方进行的更改。我已将其切换回以匹配我在生产中的代码。
猜你喜欢
  • 1970-01-01
  • 2018-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多