google-cloud-storage - gsutil cp 成功,但来自存储客户端的 upload_from_filename() 方法失败
问题描述
我想使用python中的google存储客户端将文件上传到GCS,但由于权限问题而失败,但是gsutil cp
成功了。我不明白为什么。
这是我使用的运行gsutil
:
BUCKET=abc
$ gcloud iam service-accounts keys create --iam-account $ACCOUNT key_file.json
created key [5006838b5984f1d3b4de6523239e9bbd2c7f7047] of type [json] as [key_file.json] for [serviceaccountname@myproject.iam.gserviceaccount.com]
$ gcloud auth activate-service-account --key-file key_file.json
Activated service account credentials for: [serviceaccountname@myproject.iam.gserviceaccount.com]
$ touch test.txt
$ gsutil cp test.txt gs://${BUCKET}/test.txt
Copying file://test.txt [Content-Type=text/plain]...
/ [1 files][ 0.0 B/ 0.0 B]
Operation completed over 1 objects.
这是我从python尝试过的:
from google.cloud import storage
import os
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'key_file.json' #same file as downloaded above
storage_client = storage.Client()
bucket_name = "abc" #the bucket name
source_file_name = "test.txt"
destination_blob_name = f"{source_file_name}"
with open(source_file_name, 'w') as f:
f.write("lorem ipsum")
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(source_file_name)
该upload_from_filename()
功能因错误而失败:
google.api_core.exceptions.Forbidden: 403 POST https://storage.googleapis.com/upload/storage/v1/b/abc/o?uploadType=multipart : ('Request failed with status code', 403, '预期一个的',<HTTPStatus.OK:200>)
我很困惑。我原以为如果这可以从 gsutil 工作,它可以使用 python 存储客户端工作。任何建议都将受到欢迎。
解决方案
我已经深入了解了这个问题。这是双重的。
- 我发现如果存储对象不存在,代码
destination_blob_name
会成功。如果对象确实存在,则会发生上述错误。 - 访问存储桶的权限
$ACCOUNT
由应用于存储桶的自定义角色提供。当我向该自定义角色添加权限时storage.objects.get
,storage.objects.delete
即使对象已经存在,我的代码也会成功。
我发现storage.objects.get
&storage.objects.delete
被描述为
- 读取对象数据和元数据,不包括 ACL
- 删除对象
https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions
我从中学到的知识是,在某些情况下(例如,当目标对象已经存在时)gsutil cp
需要对google.cloud.storage.blob.upload_from_filename()
. 如果有人可以阐明这两种操作之间的区别,那么我很想更好地理解它。
推荐阅读
- python - 如何防止 print() 重复每一行?
- angular - 为什么 DOM 的 Angular 没有像打字稿那样的类型安全?
- scala - 线程“主”java.io.FileNotFoundException 中的异常:t.txt(没有这样的文件或目录)
- android - 在 Android 应用程序中检测通知“发送者/触发器”
- android - 无法正确测量图标
- sql-server - 如何设置 Microsoft SQL Server 脚本或存储过程的最长执行时间
- c# - 在 Web API 中处理 API 中长时间运行的 SQL 脚本(30 分钟)
- wpf - window.postMessage VS window.chrome.webview.postMessage
- windows - 在带括号的块中回显包含右括号的变量值
- linux - 如果我在 /dev 目录中使用 vim 创建文件会发生什么。由于 /dev 不是标准文件系统,文件将如何创建