3

我面临的问题是 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
4

2 回答 2

6

如果您拥有的 Cloud Function 是由 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,然后您可以随心所欲地使用它。

于 2019-11-01T12:16:03.427 回答
1

如果您的目标是处理每个(或大部分)上传的文件,@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']

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

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

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

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

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

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

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

此类过滤还可用于根据当前日期/时间限制您在列表中获得的条目数量,这可能会显着加快您的函数执行速度,特别是如果上传了许多此类文件(您的命名建议表明可能存在很多)

于 2019-11-02T14:37:12.173 回答