我正在创建一个演示管道,使用免费的Google帐户将CSV文件与Dataflow一起加载到BigQuery中。这就是我所面对的。
当我从GCS文件中读取并仅记录数据时,这将非常有效。下面是我的示例代码。
此代码可以正常运行
DataflowPipelineOptions options = PipelineOptionsFactory.as(DataflowPipelineOptions.class);
options.setProject("project12345");
options.setStagingLocation("gs://mybucket/staging");
options.setRunner(DataflowRunner.class);
DataflowRunner.fromOptions(options);
Pipeline p = Pipeline.create(options);
p.apply(TextIO.read().from("gs://mybucket/charges.csv")).apply(ParDo.of(new DoFn<String, Void>() {
@ProcessElement
public void processElement(ProcessContext c) {
LOG.info(c.element());
}
}));
但是,当我添加一个临时文件夹位置以及创建的存储桶的路径时,出现错误,下面是我的代码。
LOG.debug("Starting Pipeline");
DataflowPipelineOptions options = PipelineOptionsFactory.as(DataflowPipelineOptions.class);
options.setProject("project12345");
options.setStagingLocation("gs://mybucket/staging");
options.setTempLocation("gs://project12345/temp");
options.setJobName("csvtobq");
options.setRunner(DataflowRunner.class);
DataflowRunner.fromOptions(options);
Pipeline p = Pipeline.create(options);
boolean isStreaming = false;
TableReference tableRef = new TableReference();
tableRef.setProjectId("project12345");
tableRef.setDatasetId("charges_data");
tableRef.setTableId("charges_data_id");
p.apply("Loading Data from GCS", TextIO.read().from("gs://mybucket/charges.csv"))
.apply("Convert to BiqQuery Table Row", ParDo.of(new FormatForBigquery()))
.apply("Write into Data in to Big Query",
BigQueryIO.writeTableRows().to(tableRef).withSchema(FormatForBigquery.getSchema())
.withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_IF_NEEDED)
.withWriteDisposition(isStreaming ? BigQueryIO.Write.WriteDisposition.WRITE_APPEND
: BigQueryIO.Write.WriteDisposition.WRITE_TRUNCATE));
p.run().waitUntilFinish();
}
运行此命令时,出现以下错误
Exception in thread "main" java.lang.IllegalArgumentException: DataflowRunner requires gcpTempLocation, but failed to retrieve a value from PipelineOptions
at org.apache.beam.runners.dataflow.DataflowRunner.fromOptions(DataflowRunner.java:242)
at demobigquery.StarterPipeline.main(StarterPipeline.java:74)
Caused by: java.lang.IllegalArgumentException: Error constructing default value for gcpTempLocation: tempLocation is not a valid GCS path, gs://project12345/temp.
at org.apache.beam.sdk.extensions.gcp.options.GcpOptions$GcpTempLocationFactory.create(GcpOptions.java:247)
at org.apache.beam.sdk.extensions.gcp.options.GcpOptions$GcpTempLocationFactory.create(GcpOptions.java:228)
at org.apache.beam.sdk.options.ProxyInvocationHandler.returnDefaultHelper(ProxyInvocationHandler.java:592)
at org.apache.beam.sdk.options.ProxyInvocationHandler.getDefault(ProxyInvocationHandler.java:533)
at org.apache.beam.sdk.options.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:155)
at com.sun.proxy.$Proxy15.getGcpTempLocation(Unknown Source)
at org.apache.beam.runners.dataflow.DataflowRunner.fromOptions(DataflowRunner.java:240)
这是身份验证的问题吗?因为我通过Eclipse Dataflow插件从GCP使用json凭据作为项目所有者。
任何帮助将不胜感激。
答案 0 :(得分:0)
看起来像是从[1]抛出的错误消息。默认的GCS验证器在[2]中实现。如您所见,Beam代码还引发IllegalArgumentException
的原因异常。因此,您可以进一步检查堆栈中是否有GcsPathValidator
中发生的异常。
答案 1 :(得分:0)
它可能与您正在设置的流式传输选项有关。 CSV上传自动设置为批处理作业。因此,如果您尝试将其设置为流,可能会导致问题。
如果您坚持要进行流式传输,请查看this documentation。
答案 2 :(得分:0)
也许您缺少凭据?由于您需要创建一个文件夹结构(每次执行一个新文件夹),因此需要Storage Admin
而不是Storage Object Admin
或Storage Object Creator
。
答案 3 :(得分:0)
这可能有多种原因:
您没有使用正确的 GCP 项目凭据登录 - 错误的用户(或没有登录的用户)或错误的 正在登录项目
确保 GOOGLE_APPLICATION_CREDENTIALS 环境变量 适用于正确的用户和项目。如果没有获得权利 凭据使用
gcloud auth 应用程序-默认登录
下载json,将GOOGLE_APPLICATION_CREDENTIALS改为下载的文件。重新启动系统,然后重试
您可以使用正确的用户 ID 登录正确的项目, 但存储桶访问的必要权限可能不存在。 确保您具有以下访问权限:
您尝试的网址不存在或拼写错误