我面临的问题是,当我使用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
答案 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.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']
请注意,最近上传的文件实际上是列表中的最后一个文件,而不是第一个文件。因此,您要做的就是将索引0
替换为索引-1
。
要考虑的其他一些可能的事情/原因(尝试打印fileList
以确认/否认这些理论):
您期望在索引-1
中找到的文件实际上并未完全上传并完成。我不确定在这种情况下您是否可以做任何事情-这仅仅是管理期望的问题
返回的文件列表实际上并未按字典顺序排序(无论出于何种原因)。我看到Listing Objects提到了排序,但Storage Client API文档没有提到。在需要时,在从索引fileList
选取文件之前,对-1
进行显式排序应该可以解决此问题。
在该存储桶中具有不遵循提及的命名规则的文件(无论出于何种原因)-任何这样的文件(其名称都位于最近上传的文件之后)将完全破坏您的算法。为了防止这种情况,您可以使用prefix
的{{1}}以及delimiter
可选参数来根据需要过滤结果。来自上述API文档:
前缀(str)–(可选)用于过滤斑点的前缀。
定界符(str)–(可选)定界符,与前缀一起用于模拟层次结构。
这种过滤也可以用于限制基于当前日期/时间在列表中获得的条目数量,可能可以显着加快函数执行速度,尤其是在存在许多此类文件的情况下上传(您的命名建议表明可能有很多)