使用 Apache Libcloud 上传到 GCS 时,对象元数据键小写

Object metadata keys are lowercased when uploading to GCS with Apache Libcloud

我正在使用 Apache Libcloud 将文件连同对象元数据一起上传到 Google Cloud Storage 存储桶。

在此过程中,我的元数据字典中的键被小写。我不确定这是由于 Cloud Storage 还是在 Libcloud 中发生的。

可以按照 Libcloud docs 中的示例重现该问题:

from libcloud.storage.types import Provider
from libcloud.storage.providers import get_driver

cls = get_driver(Provider.GOOGLE_STORAGE)
driver = cls('SA-EMAIL', './SA.json') # provide service account credentials here


FILE_PATH = '/home/user/file'

extra = {'meta_data': {'camelCase': 'foo'}}

# Upload with metadata
with open(FILE_PATH, 'rb') as iterator:
    obj = driver.upload_object_via_stream(iterator=iterator,
                                          container=container,
                                          object_name='file',
                                          extra=extra)

文件上传成功,但生成的元数据如下所示:

其中camelCase已经变成了camelcase

我不认为 GCS 不允许对象元数据使用驼峰命名法,因为在这种意义上可以手动编辑元数据:

我浏览了 Libcloud 的源代码,但没有看到任何明确的小写化。欢迎提供有关如何使用 libcloud 上传驼峰式元数据的任何指示。

我也检查了 library and wasn't able to see anything obvious. But I guess to open a new issue there 将是一个很好的开始。

就 Google 云存储方面的关注而言,您可以自己验证它确实承认驼峰式。我能够使用他们 public docs 上提供的代码成功编辑文件的元数据(但无法在 libcloud 本身上找出一些东西):

from google.cloud import storage


def set_blob_metadata(bucket_name, blob_name):
    """Set a blob's metadata."""
    # bucket_name = 'your-bucket-name'
    # blob_name = 'your-object-name'

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.get_blob(blob_name)
    metadata = {'camelCase': 'foo', 'NaMe': 'TeSt'}
    blob.metadata = metadata
    blob.patch()

    print("The metadata for the blob {} is {}".format(blob.name, blob.metadata))

所以,如果您无法使用 libcloud 解决问题,我相信这可能是您的案例的一个很好的解决方法。请注意,云存储客户端库的身份验证基于环境变量和以下 docs should be followed.

问题作者的补充:正如评论中所暗示的,可以在上传文件之前将元数据添加到 blob,如下所示:

from google.cloud import storage
gcs = storage.Client()
bucket = gcs.get_bucket('my-bucket')
blob = bucket.blob('document')
blob.metadata = {'camelCase': 'foobar'}
blob.upload_from_file(open('/path/to/document', 'rb'))

这允许设置元数据而无需修补现有的 blob,并为 libcloud 的问题提供了有效的解决方法。