【问题标题】:Read Latest File from Google Cloud Storage Bucket Using Cloud Function使用 Cloud Function 从 Google Cloud Storage Bucket 读取最新文件
【发布时间】:2019-11-01 11:09:34
【问题描述】:

我面临的问题是 Cloud Storage 按字典顺序(字母顺序)对新添加的文件进行排序,而我正在使用 Cloud Functions 中的 python 客户端库读取放置在 Cloud Storage 存储桶中索引 0 的文件(使用云函数是必须作为我项目的一部分)并将数据放入 BigQuery 中,这对我来说工作正常,但新添加的文件并不总是出现在索引 0 处。

流媒体文件每天在不同时间进入我的存储桶。 文件名相同(data-2019-10-18T14_20_00.000Z-2019-10-18T14_25_00.txt),但文件名中的日期和时间字段在每个新添加的文件中都不同。

如何调整此python代码以在每次触发云功能时读取Cloud Storage存储桶中最新添加的文件?

files = bucket.list_blobs()
fileList = [file.name for file in files if '.' in file.name]
blob = bucket.blob(fileList[0])   #reading file placed at index 0 in bucket

【问题讨论】:

    标签: python google-cloud-platform google-cloud-functions google-cloud-storage client-library


    【解决方案1】:

    如果您拥有的云功能是由 HTTP 触发的,那么您可以将其替换为使用 Google Cloud Storage Triggers 的云功能。如果它已经存在,那么您只需要利用它。

    任何时候触发该函数,您都可以检查事件类型并对数据执行任何操作,例如:

    from google.cloud import storage
    
    storage_client = storage.Client()
    
    def hello_gcs_generic(data, context):
        """Background Cloud Function to be triggered by Cloud Storage.
           check more in https://cloud.google.com/functions/docs/calling/storage#functions-calling-storage-python
        """
    
        if context.event_type == storage.notification.OBJECT_FINALIZE_EVENT_TYPE:
    
            print('Created: {}'.format(data['timeCreated'])) #this here for illustration purposes
            print('Updated: {}'.format(data['updated']))
    
            blob = storage_client.get_bucket(data['bucket']).get_blob(data['name']) 
    
            #TODO whatever else needed with blob
    

    这样,您不必关心对象的创建时间。您知道在创建时您的客户端库代码会获取相应的 blob,然后您可以随心所欲地使用它。

    【讨论】:

      【解决方案2】:

      如果您的目标是处理每个(或大部分)上传的文件,@fhenrique 的答案是更好的方法。

      但是,如果您的处理与文件上传的速度相比相当稀疏(或者只是如果您的要求不允许您切换到建议的 Cloud Storage 触发器),那么您需要仔细查看为什么不满足您在索引 0 位置找到最近上传的文件的期望。

      首先想到的原因是您的文件命名约定。例如,假设有 2 个这样的文件:data-2019-10-18T14_20_00.000Z-2019-10-18T14_25_00.txt 和 data-2019-10-18T14_25_00.000Z-2019-10-18T14_30_00.txt。他们的 字典顺序是:

      ['data-2019-10-18T14_20_00.000Z-2019-10-18T14_25_00.txt',
       'data-2019-10-18T14_25_00.000Z-2019-10-18T14_30_00.txt']
      

      请注意,最近上传的文件实际上是列表中的最后一个,而不是第一个。所以你所要做的就是用索引-1替换索引0。

      需要考虑的其他一些可能的事情/原因(尝试打印 fileList 以确认/否认这些理论):

      • 您希望在索引-1 位置找到的文件实际上并未完全上传和完成。我不确定在这种情况下您是否可以做些什么 - 这只是管理期望的问题

      • 返回的文件列表实际上并未按字典顺序排序(无论出于何种原因)。我看到Listing Objects 中提到了排序,但Storage Client API 文档中没有。如果需要,在选择索引-1 处的文件之前显式排序fileList 应该注意这一点。

      • 在该存储桶中包含不遵循上述命名规则的文件(无论出于何种原因) - 任何此类文件的名称都位于最近上传的文件之后,这将完全破坏您的算法。为了防止出现这种情况,您可以使用prefix 和delimiter 可选参数来根据需要过滤结果。来自上述 API 文档:

      • prefix (str) – (可选)用于过滤 blob 的前缀。

      • delimiter (str) – (可选)分隔符,与前缀一起使用以模拟层次结构。

      这种过滤还可以用于根据当前日期/时间限制您在列表中获得的条目数量,这可能显着加快您的函数执行速度,尤其是在有很多此类文件的情况下上传(您的命名建议表明可能有很多)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-08
        • 2020-06-13
        • 2019-11-17
        • 1970-01-01
        • 2020-05-05
        • 2015-04-09
        • 2019-02-14
        • 1970-01-01
        相关资源
        最近更新 更多