首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Cloud Function从Google Cloud Storage Bucket读取最新文件

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

Stack Overflow用户
提问于 2019-11-01 19:09:34
回答 2查看 3.1K关注 0票数 3

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

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

如何调整这段python代码,使其在每次触发云函数时都能读取云存储存储桶中最新添加的文件?

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2019-11-01 20:16:03

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

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

代码语言:javascript
复制
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,然后您可以随心所欲地处理它。

票数 5
EN

Stack Overflow用户

发布于 2019-11-02 22:37:12

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

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

我想到的第一个原因是您的文件命名约定。例如,假设有两个这样的文件: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。它们的字典顺序是:

代码语言:javascript
复制
['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位置找到的文件实际上并没有完全上载和完成。我不确定在这种情况下你能做些什么--这只是一个简单的管理expectations
  • the列表的问题,返回的文件列表实际上并没有按字典顺序排序(不管是什么原因)。我在Listing Objects中看到了排序,但在Storage Client应用编程接口文档中没有提到。如果存储桶中的needed.
  • having文件不遵循前面提到的命名规则(无论出于什么原因),在选择索引-1处的文件之前显式排序fileList应该注意到这一点-任何这样的文件,其名称位于最近上传的文件之后,都将完全破坏您的算法。为了防止出现这种情况,您可以使用prefix,也可以使用bucket.list_blobs()delimiter可选参数来根据需要过滤结果。来自上述接口文档:

前缀前缀( blobs.

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

这种过滤对于根据当前日期/时间限制列表中的条目数量也很有用,这可能会显著加快函数的执行速度,特别是当上传了许多这样的文件时(您的命名建议表明可能有很多这样的文件)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58658228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档