使用 gcloud cli 执行具有多个 inputs/outputs 的数据流作业

Executing a Dataflow job with multiple inputs/outputs using gcloud cli

我已经在 Dataprep 中设计了一个数据转换,现在正尝试使用 Dataflow 中的模板运行它。我的流程有几个输入和输出 - 数据流模板将它们作为 json 对象提供,每个输入和位置都有 key/value 对。它们看起来像这样(添加了换行符以便于阅读):

{
    "location1": "project:bq_dataset.bq_table1",
    #...
    "location10": "project:bq_dataset.bq_table10",
    "location17": "project:bq_dataset.bq_table17"
}

我有 17 个输入(主要是查找)和 2 个输出(一个 csv,一个 bigquery)。我将这些传递给 gcloud CLI,如下所示:

gcloud dataflow jobs run job-201807301630 /
    --gcs-location=gs://bucketname/dataprep/dataprep_template /
    --parameters inputLocations={"location1":"project..."},outputLocations={"location1":"gs://bucketname/output.csv"}

但是我收到一个错误:

ERROR: (gcloud.dataflow.jobs.run) unrecognized arguments:
inputLocations=location1:project:bq_dataset.bq_table1,outputLocations=location2:project:bq_dataset.bq_output1
inputLocations=location10:project:bq_dataset.bq_table10,outputLocations=location1:gs://bucketname/output.csv

从错误消息来看,它看起来是在合并输入和输出,因此当我有两个输出时,每两个输入都与两个输出配对:

input1:output1
input2:output2
input3:output1
input4:output2
input5:output1
input6:output2
...

我尝试引用 input/output 对象(单引号和双引号,加上删除对象中的引号),将它们包装在 [] 中,使用波浪号但没有乐趣。有没有人设法执行具有多个输入的数据流作业?

经过大量的反复试验,我终于找到了解决方案。涉及几个步骤。

--parameters

的格式

--parameters参数是一个字典类型的参数。您可以通过在 CLI 中键入 gcloud topic escaping 来阅读文档中关于这些的详细信息,但简而言之,这意味着您需要在 --parameters 和参数之间添加一个 =,然后是格式是键=值对,值用引号括起来 ("):

--parameters=inputLocations="object",outputLocations="object"

逃脱对象

然后,对象需要引号转义以避免过早结束值,所以

{"location1":"gcs://bucket/whatever"...

变成

{\"location1\":\"gcs://bucket/whatever\"...

选择不同的分隔符

接下来,CLI 会感到困惑,因为虽然键=值对由逗号分隔,但值在对象中也有逗号。因此,您可以通过将其放在参数开头的克拉 (^) 和键=值对之间来定义不同的分隔符:

--parameters=^*^inputLocations="{"\location1\":\"...\"}"*outputLocations="{"\location1\":\"...\"}"

我使用 * 是因为 ; 不起作用 - 可能是因为它标志着 CLI 命令的结束?谁知道呢

另请注意,gcloud topic escaping 信息显示:

In cmd.exe and PowerShell on Windows, ^ is a special character and you must escape it by repeating it. In the following examples, every time you see ^, replace it with ^^^^.

别忘了customGcsTempLocation

毕竟,我忘记了 customGcsTempLocation 需要添加到 --parameters 参数中的键=值对。不要忘记用 * 将它与其他的分开,并再次用引号引起来:

...}*customGcsTempLocation="gs://bucket/whatever"

几乎 none 在线文档中对此进行了解释,所以这是我生命中的几天我不会回来 - 希望我已经帮助了其他人。