【问题标题】:In BigQuery, query to get GCS metadata (filenames in GCS)在 BigQuery 中,查询以获取 GCS 元数据(GCS 中的文件名)
【发布时间】:2022-11-17 09:20:09
【问题描述】:

我们有一个 GCS 存储桶,其子文件夹位于 url https://storage.googleapis.com/our-bucket/path-to-subfolder。此子文件夹包含文件:

  • file_1_3.png
  • file_7_4.png
  • file_3_2.png
  • file_4_1.png

我们想在 BigQuery 中创建一个包含一列的表1号值为 1,7,3,4(文件名中的第一个数字)和一列2号与第二个数字。一旦数据(带有文件名的列)在 BigQuery 中,字符串拆分就很容易了。如何检索文件名?是否可以查询文件元数据的 GCS 存储桶?

编辑:想做this

【问题讨论】:

    标签: google-bigquery google-cloud-storage


    【解决方案1】:

    更新答案以反映如何检索文件上的 GCS Bucket 元数据的问题。

    根据用例,您可以在此处选择两个选项:

    1. 在 cron 计划上使用云函数来执行元数据读取(如您共享的示例中所示),然后使用 BQ 客户端库执行插入。然后执行下面列出的正则表达式。
    2. 此选项在预览中使用了一项功能(远程功能),因此您可能没有所需的功能,但可以请求它。此选项将为您提供最新的读取数据。它涉及以下内容:
      • 创建一个返回 blob 名称数组的云函数,请参见下面的代码。
      • 在 BigQuery 中创建一个连接资源(整个过程在 here 中列出,但是由于远程功能部分在预览文档中,并且您的 UI 可能无法反映必要的选项(在我的中没有)。
      • 创建一个remote function(链接中的第三个代码块)
      • 从您的代码中调用该函数,然后根据需要使用正则表达式进行操作。

      选项 2 的示例 CF:

      from google.cloud import storage
      
      def list_blobs(bucket_name):
          """Lists all the blobs in the bucket."""
      
          storage_client = storage.Client()
      
          # Note: Client.list_blobs requires at least package version 1.17.0.
          blobs = storage_client.list_blobs(bucket_name)
          blob_array = []
      
          for blob in blobs:
              blob_array.append()
      
          return blob_array
      

      文档中的示例远程功能:

      CREATE FUNCTION mydataset.remoteMultiplyInputs(x FLOAT64, y FLOAT64)
      RETURNS FLOAT64
      REMOTE WITH CONNECTION us.myconnection
      OPTIONS(endpoint="https://us-central1-myproject.cloudfunctions.net/multiply");
      

      一旦进入,它将返回文件的完整 gcs 路径。从那里你可以像下面的regexp_extract(_FILE_NAME, 'file_(.+)_')一样使用正则表达式来提取重要信息。

    【讨论】:

    • 你注意到文件扩展名了吗?它是PNG:o)
    • 我没有注意到
    • @MikhailBerlyant 我不是要查询数据里面任何单个文件。我正在尝试查询目录所有文件名.
    • @Canovice - 这正是我提到扩展的重点。因为这个答案假定查询文件:o)
    • 希望 G 会提供一些像这样的公共 RF 代码,就像他们为 SQL UDF 所做的那样...值。然后,您可以使用一个函数查询任何 API...
    【解决方案2】:

    既然 BQ 远程函数 (RF) 既是 GA 又是 JSON,我想分享一种直接从 BQ SQL 获取存储桶中 blob 的任何属性的方法。 仔细阅读有关如何设置 RF 的官方文档,因为很容易漏掉一个步骤。

    1. 创建以下 storage Cloud Function(此处为 Python)- 第一代足够好:
      import json
      from google.cloud import storage
      
      storage_client = storage.Client()
      
      def list_blobs(request):
          print(request_json := request.get_json())  # print for debugging
          calls = request_json['calls']
          
          bucket_name = calls[0][0]
          blobs = storage_client.list_blobs(bucket_name)
          
          reply = [b._properties for b in blobs]
          return json.dumps({'replies': [reply]})
      
      1. 创建 BQ 远程函数(假设fns数据集、us.api连接和my_project_id):
      CREATE FUNCTION fns.list_blobs(bucket STRING)
      RETURNS JSON
      REMOTE WITH CONNECTION us.api
      OPTIONS(endpoint="https://us-central1-my_project_id.cloudfunctions.net/storage")
      
      1. SELECT你想要的任何属性
      SELECT STRING(blob.name), STRING(blob.size), CAST(STRING(blob.updated) AS TIMESTAMP)
      FROM
        UNNEST(
          JSON_EXTRACT_ARRAY(
            fns.list_blobs('my_bucket')
          )
        ) blob
      

      瞧!我希望有一种更简单的方法可以将 JSON 数组完全解析为表,一次填充所有列,但在撰写本文时,您必须明确提取所需的属性:

      你可以通过扩展功能(云和远程)来做更多很酷的事情,这样你就不必离开 SQL,比如,

      • 生成并返回签名 URL 以直接从查询结果(例如 BI 工具)中显示/下载
      • 在 CF 代码中使用 user_defined_context 和分支逻辑,执行其他操作,如删除 blob 或做其他事情

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2020-01-25
      • 1970-01-01
      相关资源
      最近更新 更多