Sondea la finalización del trabajo de BigQuery

Cuando inicias un trabajo de BigQuery con el conector de BigQuery, es posible que tu flujo de trabajo no espere automáticamente a que se complete el trabajo. Si los pasos posteriores dependen del éxito del trabajo, debes implementar un mecanismo de sondeo.

Muchos conectores de Workflows muestran un recurso de operación de larga duración (LRO) que se puede sondear. Si bien algunos conectores muestran un recurso de tipo Operation para representar un LRO, BigQuery usa un Job recurso para este propósito. Otros servicios, como Cloud Build o Compute Engine, muestran un recurso Operation real. Para obtener una lista de los tipos de recursos de LRO, consulta Conectores compatibles.

Sondeo automático

Puedes sondear automáticamente la finalización de un trabajo de BigQuery cuando usas métodos de conector que muestran un recurso de LRO, como googleapis.bigquery.v2.jobs.insert.

Cuando usas un método de conector de este tipo, Workflows bloquea la ejecución del flujo de trabajo hasta que la operación se realiza correctamente o falla. El campo connector_params te permite personalizar el comportamiento de sondeo, incluido el tiempo de espera total y la frecuencia de las verificaciones de estado. Para obtener más información, consulta Cómo invocar una llamada de conector.

Por ejemplo, el siguiente flujo de trabajo muestra cómo iniciar un trabajo de BigQuery con el método jobs.insert y configurar el sondeo del trabajo con una política que usa parámetros personalizados en lugar de los parámetros predeterminados:

YAML

# This workflow demonstrates how to automatically poll for the completion of
# a BigQuery job when using a connector method that return an LRO resource.
main:
  steps:
    - init:
        assign:
          - project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
          - query: "SELECT * FROM `bigquery-public-data.usa_names.usa_1910_2013` LIMIT 10"
    - run_bigquery_job:
        call: googleapis.bigquery.v2.jobs.insert
        args:
          projectId: ${project_id}
          body:
            configuration:
              query:
                query: ${query}
                useLegacySql: false
          connector_params:
            timeout: 3600  # Total time in seconds to wait for the job; default is 1800
            polling_policy:
              initial_delay: 2.0  # Seconds to wait before the first poll; default is 1.0
              multiplier: 1.5     # Factor by which to increase delay between polls; default is 1.25
              max_delay: 60.0     # Maximum delay in seconds between polls; default is 60.0
        result: job_status
    - finish:
        return: ${job_status}

JSON

{
  "main": {
    "steps": [
      {
        "init": {
          "assign": [
            {
              "project_id": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_ID\")}"
            },
            {
              "query": "SELECT * FROM `bigquery-public-data.usa_names.usa_1910_2013` LIMIT 10"
            }
          ]
        }
      },
      {
        "run_bigquery_job": {
          "call": "googleapis.bigquery.v2.jobs.insert",
          "args": {
            "projectId": "${project_id}",
            "body": {
              "configuration": {
                "query": {
                  "query": "${query}",
                  "useLegacySql": false
                }
              }
            },
            "connector_params": {
              "timeout": 3600,
              "polling_policy": {
                "initial_delay": 2,
                "multiplier": 1.5,
                "max_delay": 60
              }
            }
          },
          "result": "job_status"
        }
      },
      {
        "finish": {
          "return": "${job_status}"
        }
      }
    ]
  }
}

Sondeo manual

El sondeo automático solo se aplica a los métodos que muestran un recurso de LRO. Los métodos síncronos estándar como googleapis.bigquery.v2.jobs.query no admiten el sondeo automático y pueden requerir un sondeo manual si la consulta tarda más que el tiempo de espera interno de la API.

Por ejemplo, el siguiente flujo de trabajo muestra cómo sondear la finalización de un trabajo de BigQuery directamente en el flujo de trabajo con el getQueryResults método:

YAML

# This workflow demonstrates how to manually poll for the completion of
# a BigQuery job by using the `getQueryResults` method.
main:
  steps:
    - init:
        assign:
          - project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
    - startQuery:
        call: googleapis.bigquery.v2.jobs.query
        args:
          projectId: ${project_id}
          body:
            useLegacySql: false
            query: "SELECT * FROM `bigquery-public-data.usa_names.usa_1910_2013` LIMIT 10"
        result: queryResponse
    - getJobId:
        assign:
          - jobId: ${queryResponse.jobReference.jobId}
    - pollingLoop:
        steps:
          - checkStatus:
              call: googleapis.bigquery.v2.jobs.getQueryResults
              args:
                projectId: ${project_id}
                jobId: ${jobId}
                timeoutMs: 10000  # Default wait time per call
              result: jobStatus
          - checkIfDone:
              switch:
                - condition: ${jobStatus.jobComplete}
                  return: ${jobStatus}  # Job is finished
          - wait:
              call: sys.sleep
              args:
                seconds: 5
              next: checkStatus  # Repeat check

JSON

{
  "main": {
    "steps": [
      {
        "init": {
          "assign": [
            {
              "project_id": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_ID\")}"
            }
          ]
        }
      },
      {
        "startQuery": {
          "call": "googleapis.bigquery.v2.jobs.query",
          "args": {
            "projectId": "${project_id}",
            "body": {
              "useLegacySql": false,
              "query": "SELECT * FROM `bigquery-public-data.usa_names.usa_1910_2013` LIMIT 10"
            }
          },
          "result": "queryResponse"
        }
      },
      {
        "getJobId": {
          "assign": [
            {
              "jobId": "${queryResponse.jobReference.jobId}"
            }
          ]
        }
      },
      {
        "pollingLoop": {
          "steps": [
            {
              "checkStatus": {
                "call": "googleapis.bigquery.v2.jobs.getQueryResults",
                "args": {
                  "projectId": "${project_id}",
                  "jobId": "${jobId}",
                  "timeoutMs": 10000
                },
                "result": "jobStatus"
              }
            },
            {
              "checkIfDone": {
                "switch": [
                  {
                    "condition": "${jobStatus.jobComplete}",
                    "return": "${jobStatus}"
                  }
                ]
              }
            },
            {
              "wait": {
                "call": "sys.sleep",
                "args": {
                  "seconds": 5
                },
                "next": "checkStatus"
              }
            }
          ]
        }
      }
    ]
  }
}

¿Qué sigue?