我正在实现Pub / Sub到BigQuery管道。它看起来类似于How to create read transform using ParDo and DoFn in Apache Beam,但在这里,我已经创建了一个PCollection。
我正在遵循Apache Beam documentation中描述的内容,以执行ParDo操作以使用以下管道来准备表行:
static class convertToTableRowFn extends DoFn<PubsubMessage, TableRow> {
@ProcessElement
public void processElement(ProcessContext c) {
PubsubMessage message = c.element();
// Retrieve data from message
String rawData = message.getData();
Instant timestamp = new Instant(new Date());
// Prepare TableRow
TableRow row = new TableRow().set("message", rawData).set("ts_reception", timestamp);
c.output(row);
}
}
// Read input from Pub/Sub
pipeline.apply("Read from Pub/Sub",PubsubIO.readMessagesWithAttributes().fromTopic(topicPath))
.apply("Prepare raw data for insertion", ParDo.of(new convertToTableRowFn()))
.apply("Insert in Big Query", BigQueryIO.writeTableRows().to(BQTable));
我在gist中找到了DoFn函数。
我一直收到以下错误:
The method apply(String, PTransform<? super PCollection<PubsubMessage>,OutputT>) in the type PCollection<PubsubMessage> is not applicable for the arguments (String, ParDo.SingleOutput<PubsubMessage,TableRow>)
我一直都知道ParDo / DoFn操作是逐元素的PTransform操作,对吗?我从来没有在Python中遇到过此类错误,所以对于为什么会发生这种情况我有些困惑。
答案 0 :(得分:3)
您是对的,ParDos
是逐元素的变换,您的方法看起来正确。
您看到的是编译错误。当Java编译器推断的apply()
方法的参数类型与实际输入的类型不匹配时,例如会发生这种情况。 convertToTableRowFn
。
从错误中您会看到,它看起来像Java推断apply()
的第二个参数的类型为PTransform<? super PCollection<PubsubMessage>,OutputT>
,而您传递的是ParDo.SingleOutput<PubsubMessage,TableRow>
的子类(您的convertToTableRowFn
)。查看SingleOutput
的定义,您的convertToTableRowFn
基本上就是PTransform<PCollection<? extends PubsubMessage>, PCollection<TableRow>>
。而且Java无法在期望apply
的{{1}}中使用它。
看起来可疑的是Java没有将PTransform<? super PCollection<PubsubMessage>,OutputT>
推断为OutputT
。如果您有其他错误,将无法执行此操作的原因之一。您确定也没有其他错误吗?
例如,查看PCollection<TableRow>
时您正在调用convertToTableRowFn
,当我尝试执行该操作时它不存在,并且在那里编译失败。就我而言,我需要执行以下操作:message.getData()
。另外rawData = new String(message.getPayload(), Charset.defaultCharset())
期望一个字符串(例如代表BQ表名的字符串)作为参数,并且您传递了一些未知符号.to(BQTable))
(虽然它存在于您的程序中,但这不是一个问题)。
修复了这两个错误后,您的代码将为我编译,BQTable
被完全推断出并且类型兼容。