繁体   English   中英

如何在特定文件集从谷歌云到达云存储时启动云数据流管道 function

[英]how to launch a cloud dataflow pipeline when particular set of files reaches Cloud storage from a google cloud function

我需要创建一个云 function,它应该检查 GCS 存储桶中的一组文件,如果所有这些文件都到达 GCS 存储桶中,那么只有它应该为所有这些文件启动数据流模板。

我现有的云 function 代码为进入 GCS 存储桶的每个文件启动云数据流。 它根据命名约定为不同的文件运行不同的数据流。 这个现有代码工作正常,但我的意图不是直接为每个上传的文件触发数据流。 它应该检查一组文件,如果所有文件都到达,那么它应该为这些文件启动数据流。

有没有一种方法可以使用 Cloud Functions 来做到这一点,或者是否有另一种方法可以达到预期的结果?

from googleapiclient.discovery import build
import time
def df_load_function(file, context):
filesnames = [
    'Customer_',
    'Customer_Address',
    'Customer_service_ticket'
    ]

# Check the uploaded file and run related dataflow jobs.
for i in filesnames:
    if 'inbound/{}'.format(i) in file['name']:
        print("Processing file: {filename}".format(filename=file['name']))

        project = 'xxx'
        inputfile = 'gs://xxx/inbound/' + file['name']
        job = 'df_load_wave1_{}'.format(i)
        template = 'gs://xxx/template/df_load_wave1_{}'.format(i)
        location = 'asia-south1'
       
        dataflow = build('dataflow', 'v1b3', cache_discovery=False)
        request = dataflow.projects().locations().templates().launch(
            projectId=project,
            gcsPath=template,
            location=location,
            body={
                'jobName': job,
                "environment": {
                "workerRegion": "asia-south1",
                "tempLocation": "gs://xxx/temp" 
            }
            }
        )

        # Execute the dataflowjob
        response = request.execute()
        
        job_id = response["job"]["id"]

我已经为上述功能编写了以下代码。 云 function 正在运行,没有任何错误,但它没有触发任何数据流。 不确定发生了什么,因为日志没有错误。

from googleapiclient.discovery import build
import time
import os
def df_load_function(file, context):
            filesnames = [
    'Customer_',
    'Customer_Address_',
    'Customer_service_ticket_'
]
paths =['Customer_','Customer_Address_','Customer_service_ticket_']
for path in paths :
if os.path.exists('gs://xxx/inbound/')==True :
    # Check the uploaded file and run related dataflow jobs.
        for i in filesnames:
            if 'inbound/{}'.format(i) in file['name']:
                print("Processing file: {filename}".format(filename=file['name']))

                project = 'xxx'
                inputfile = 'gs://xxx/inbound/' + file['name']
                job = 'df_load_wave1_{}'.format(i)
                template = 'gs://xxx/template/df_load_wave1_{}'.format(i)
                location = 'asia-south1'
       
                dataflow = build('dataflow', 'v1b3', cache_discovery=False)
                request = dataflow.projects().locations().templates().launch(
                projectId=project,
                gcsPath=template,
                location=location,
                body={
                'jobName': job,
                "environment": {
                "workerRegion": "asia-south1",
                "tempLocation": "gs://xxx/temp" 
            }
            }
        )

        # Execute the dataflowjob
                response = request.execute()
        
                job_id = response["job"]["id"]
            
            else:
                exit()

有人可以帮我解决上面的 python 代码吗? 此外,我的文件名末尾包含当前日期,因为这些是我从不同来源团队获得的增量文件。

如果我正确理解您的问题,最简单的方法是在您的 function 中编写基本逻辑,以确定整组文件是否存在。 如果不是,请退出 function。如果是,请运行相应的数据流管道。 基本上将您在第一段中写的内容实现为 Python 代码。

如果它是一小组文件,则在每次上传时运行 function 以检查集的完整性应该不是问题。 例如,即使每月处理 10,000 个文件,该服务的成本也非常低,假设:

  1. 您的 function 没有使用大量带宽来传输数据
  2. 每次 function 调用的代码运行时间不会很长。

即使在您无法满足这些要求的情况下,Functions 的运行成本仍然相当低。

如果您担心成本,我建议您查看Google Cloud 定价计算器以进行估算。

使用更新的代码进行编辑:

为此,我强烈建议使用 Google Cloud Storage Python 客户端库。 使用 os.path 可能行不通,因为搜索存储桶需要额外的基础步骤……而且可能还有比我完全理解的更多的技术细节。

要使用 Python 客户端库,请将google-cloud-storage添加到您的 requirements.txt。 然后,使用类似于以下代码的代码来检查 object 是否存在。此示例基于 HTTP 触发器,但检查 object 是否存在的代码的要点是相同的。

from google.cloud import storage
import os

def hello_world(request):
    # Instantiate GCS client
    client = storage.client.Client()

    # Instantiate bucket definition
    bucket = storage.bucket.Bucket(client, name="bucket-name")

    # Search for object
    for file in filenames:
        if storage.blob.Blob(file, bucket) and "name_modifier" in file:
          # Run name_modifier Dataflow job
        elif storage.blob.Blob(file, bucket) and "name_modifier_2" in file:
          # Run name_modifier_2 Dataflow job
        else:
          return "File not found"

从逻辑的角度来看,这段代码并不完全是您想要的,但应该可以帮助您入门。 您可能只想确保首先找到所有对象,然后转到另一个步骤,开始为每个文件运行相应的 Dataflow 作业(如果它们在上一步中都已找到)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM