是否可以通过BigQuery Python客户端库执行非阻塞load_job?

时间:2019-10-19 10:26:28

标签: python flask google-cloud-platform google-bigquery

我有一个使用Flask_restful,Flask_CORS和棉花糖的Flask API。该API进行了一些工作,以将* .csv文件(使用signedURL的)放入Cloud Storage,确认它已上传,然后创建并执行加载作业,以将csv从Storage传输到BigQuery。 API加剧我脱发的部分是在GCP中执行将CSV文件加载到BigQuery的加载作业的调用。这是代码段:

...
            dataset_ref = bq_client.dataset(target_dataset) 
            job_config.schema =  bq_schema 
            job_config.source_format = SOURCE_FORMAT 
            job_config.field_delimiter =  DELIM  
            job_config.destination_table_description = TARGET_TABLE
            job_config.encoding = ENCODING 
            job_config.max_bad_records = MAX_BAD_RECORDS
            job_config.autodetect = False # Do not autodetect schema
            load_job = bq_client.load_table_from_uri(
                uri, dataset_ref.table(target_table), job_config=job_config
            )  # API request
            load_job.result() # **<-- This is the concern**
            return {"message": "Successfully uploaded to Bigquery"}, 200

文件可能需要花费一些时间来传输,而我担心的是,在存在一些延迟的时间段内,Web服务器将在等待传输发生时超时。我更希望执行load_job.result(),获取作业ID并返回201响应。然后,我可以使用作业ID来轮询GCP,以确定它是否成功,而不是存在客户端前端请求超时的风险,并让用户对其是否成功感到困惑。不是。

我知道load_job.result()是异步的,但是使用Flask并没有帮助。我打算切换到Quart以使用异步/等待,但不支持我的其他依赖关系,因此我将进行大量的重构。任何人都曾经使用过另一种方法来解决此类问题吗? 干杯

1 个答案:

答案 0 :(得分:1)

Quart不能解决任何问题。确实,Quart仍然需要一个正在运行的环境,它会等待并监督阻止功能,并在最后调用您回调。您的功能必须仍然运行才能执行此操作。

对此有更好的设计。我建议您看看Cloud Task。该过程如下:

  • 运行加载作业
  • 使用参数中的加载作业ID创建任务
  • 退出功能
  • 任务将触发另一个功能,该功能将检查作业是否结束
    • 如果尚未完成,请返回错误代码(不同于2XX)。
    • 完成后,返回确定的返回码(2XX)

您必须使用retry policy设置Cloud Task才能不立即重试(例如,将min-backoff设置为30s)