使用Cloud Function从Google Cloud Storage Bucket中读取最新文件

时间:2019-11-01 11:09:34

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

我面临的问题是,当我使用Cloud Functions中的python客户端库读取位于Cloud Storage存储桶中索引0的文件时,Cloud Storage按字典顺序(字母顺序)对新添加的文件进行排序(使用cloud功能是必须作为我项目的一部分),然后将数据放入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

2 个答案:

答案 0 :(得分:3)

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

每次触发函数时,您都可以检查事件类型并使用数据做任何事情,例如:

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,然后您可以对其进行任何操作。

答案 1 :(得分:0)

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

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

首先想到的是您的文件命名约定。例如,假设有2个这样的文件:data-2019-10-18T14_20_00.000Z-2019-10-18T14_25_00.txtdata-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']

请注意,最近上传的文件实际上是列表中的最后一个文件,而不是第一个文件。因此,您要做的就是将索引0替换为索引-1

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

  • 您期望在索引-1中找到的文件实际上并未完全上传并完成。我不确定在这种情况下您是否可以做任何事情-这仅仅是管理期望的问题

  • 返回的文件列表实际上并未按字典顺序排序(无论出于何种原因)。我看到Listing Objects提到了排序,但Storage Client API文档没有提到。在需要时,在从索引fileList选取文件之前,对-1进行显式排序应该可以解决此问题。

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

  
      
  • 前缀(str)–(可选)用于过滤斑点的前缀。

  •   
  • 定界符(str)–(可选)定界符,与前缀一起用于模拟层次结构。

  •   

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