【问题标题】:Create nested folders with Google Drive API使用 Google Drive API 创建嵌套文件夹
【发布时间】:2021-06-16 17:38:25
【问题描述】:

我需要使用Google Drive apiYYYY/MM/DD/HH/mm/file 的形式在Google Drive 的嵌套文件夹中添加一个新文件,其中日期是根据当前日期动态创建的。 例如:

2021/06/16/11/30/my_file.csv

我在 Python 中创建了以下脚本,但它创建的是一个文件夹(名为“2021/06/16/11/30”)而不是所需的嵌套结构(多个嵌套文件夹名为“06”、“11”和“30”)在父文件夹“2021”中:

from googleapiclient.discovery import build
import google.auth
from googleapiclient.http import MediaFileUpload

SCOPES = ['https://www.googleapis.com/auth/drive.metadata', 'https://www.googleapis.com/auth/drive']

credentials, project_id = google.auth.default(scopes=SCOPES)
service = build('drive', 'v3', credentials=credentials)

folder_id = 'parent-folder-id'

# Create folder
file_metadata = {
    'name': '2021/06/16/11/30',
    'mimeType': 'application/vnd.google-apps.folder',
    'parents': [folder_id],
}
file = service.files().create(body=file_metadata, fields='id').execute()
new_folder_id = file.get('id')
print(f'Folder ID: {new_folder_id}')

# Upload file
file_metadata = {
    'name': 'my_file.csv',
    'parents': [new_folder_id],
}
media = MediaFileUpload('my_file.csv', mimetype='text/csv', resumable=True)
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
print(f'Folder ID: {file.get("id")}')

有没有办法在一次调用中创建这样的嵌套文件夹结构,而不是在每个文件夹创建时迭代并将新文件夹 id 作为新的父 id 传递?

【问题讨论】:

  • 您是否尝试在2021 中创建文件夹2021、下一个文件夹06 等? Google 驱动器不必使用与本地系统相同的规则。它可能会将/ 视为普通字符,而不是分隔符。
  • 迭代每个文件夹可以解决嵌套结构的问题,但它会导致一个新问题,因为它每次运行命令时都会创建一个新文件夹。
  • 那么首先你必须检查文件夹是否存在——这很正常——在正常的文件系统中,你还需要先检查文件夹是否存在,然后再尝试创建它,因为它可能会引发错误。在 Linux 中,如果您尝试再次创建新文件夹,则会出现错误。在 python 标准 os.makdirs() 中,当文件夹存在时会引发错误,您必须检查 os.path.exists() 是否存在。在 web 驱动程序中甚至更糟糕,因为它们可能有两个同名的文件夹,因为它们使用 ID 来识别文件夹。

标签: python google-api google-drive-api


【解决方案1】:

修改点:

  • 在 Google Drive 中,每个文件和文件夹都由唯一的 ID 管理,而不是文件名和文件夹名。在这种情况下,当my_file.csv 的文件上传到2021/06/16/11/30/ 的嵌套文件夹时,需要从文件夹名称中检索文件夹ID。并且,当文件夹不存在时,需要创建新文件夹。
  • 为了实现这一点,不幸的是,在循环中使用了service.files().list()的方法。因为需要检查每个文件夹的ID。

当以上几点反映到你的脚本中时,它变成如下。

修改脚本:

service = build('drive', 'v3', credentials=credentials)

path = '2021/06/16/11/30' # Please set the path.
folder_id = 'parent-folder-id' # Please set the top folder ID.

# Check the folder structure and create new folder if the folder is not existing.
pathList = path.split('/')
for folder in pathList:
    q = "'" + folder_id + "' in parents and name='" + folder + "' and mimeType='application/vnd.google-apps.folder' and trashed=false"
    files = service.files().list(q=q).execute().get('files')
    if not files:
        file_metadata = {
            'name': folder,
            'mimeType': 'application/vnd.google-apps.folder',
            'parents': [folder_id],
        }
        folder_id = service.files().create(
            body=file_metadata, fields='id').execute().get('id')
    else:
        folder_id = files[0].get('id')

# Upload file
file_metadata = {
    'name': 'my_file.csv',
    'parents': [folder_id],
}
media = MediaFileUpload('my_file.csv', mimetype='text/csv', resumable=True)
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
print(f'Folder ID: {file.get("id")}')
  • 在这个修改后的脚本中,当路径为path = '2021/06/16/11/30'时,当每个文件夹中都不存在该文件夹时,创建该文件夹。当每个文件夹中都存在该文件夹时,不会创建新文件夹。

参考资料:

【讨论】:

  • 谢谢@Tanaike,我尝试了您的解决方案,它运行良好,因此我接受它作为最佳解决方案。目前,Google Drive API 似乎没有更聪明的方法来做到这一点。再次感谢您的努力:)
【解决方案2】:

files.create API 仅创建一个文件,不能在一次调用中创建多个文件。所以要回答你的问题,你需要先创建2021,将新创建的文件夹ID设置为父级,然后迭代文件夹创建(06、16等),直到到达底层。

示例:

folder_id = 'parent-folder-id'

date_array = ["2021", "06", "16", "11", "30"]

for x in date_array:
  # Create folder
  file_metadata = {
      'name': x,
      'mimeType': 'application/vnd.google-apps.folder',
      'parents': [folder_id],
  }
  file = service.files().create(body=file_metadata, fields='id').execute()
  new_folder_id = file.get('id')
  print(f'Folder ID: {new_folder_id}')
  folder_id = new_folder_id

# Upload file
file_metadata = {
    'name': 'my_file.csv',
    'parents': [folder_id],
}
media = MediaFileUpload('my_file.csv', mimetype='text/csv', resumable=True)
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
print(f'Folder ID: {file.get("id")}')

【讨论】:

  • 不幸的是,这不是一个可行的解决方案,因为它每次都会从头开始创建所有嵌套目录......例如,它将为一年中的每一天创建一个新的“2021”表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多