Beam SQL-SqlValidatorException:找不到对象“ PCOLLECTION”

时间:2019-07-01 21:43:01

标签: apache-beam beam-sql

我正在使用Beam SQL做一些实验。 我从转换PCollection<Row>中获得了SampleSource,并将其输出传递给SqlTransform

String sql1 = "select c1, c2, c3 from PCOLLECTION where c1 > 1";

下面的代码运行没有任何错误。

POutput it = p.apply(new SampleSource()).apply(SqlTransform.query(sql1));
p.run().waitUntilFinish();

但是,当我尝试以下代码行时,出现运行时错误。

POutput it = p.apply(new SampleSource());
it.getPipeline().apply(SqlTransform.query(sql1));
p.run().waitUntilFinish();

错误详细信息是

Caused by: org.apache.beam.repackaged.beam_sdks_java_extensions_sql.org.apache.calcite.sql.validate.SqlValidatorException: Object 'PCOLLECTION' not found

请提供一些提示。

1 个答案:

答案 0 :(得分:1)

它不起作用,因为您是将SqlTransform应用于管道,而不是PCollection

您可能希望按照以下方式进行更改:


// source probably returns a PCollection,
// would make sense to change 'it' to PCollection:
PCollection<...> it = p.apply(new SampleSource());

// then apply SqlTransform to the PCollection from the previous step,
// that is apply it directly to 'it':
it.apply(SqlTransform.query(sql1));

...

从较高的角度看,Beam管道的工作原理:

  • 创建管道;
  • 应用从某个来源读取的IO PTransform,并生成从该来源读取的某些元素的PColelction
  • 将上一步中的更多PTransforms链接到PCollection上以处理数据(概念上,每个步骤都会产生不同的PCollections);
  • 重复;

SqlTransform是普通的PTransform,预期将其应用于元素PCollection并输出另一个PCollection。您在SqlTransform.create()中指定的查询将应用于PCollection。它期望数据来自神奇的PCOLLECTION表,该表代表您将PCollection应用于的SqlTransform

您在示例中所做的是不同的:

  • 创建管道;
  • 应用来源PTransform,该来源产生POutput不一定是PCollection;
  • 然后,如果您将其作为源,则忽略输出,而是采用原始管道并直接对其应用SqlTransform

因此,发生的情况是在这种情况下,SqlTransform应用于管道的“根”,而不是源于源头的PCollection。现在,您有两个PTransforms彼此独立地应用于根,而不是依次应用PTransforms的链。

另一个警告是SqlTransform期望输入元素为Rows,因为SQL作为一种语言仅适用于表示为行的数据。有两种方法可以实现此目的:

  • 通过在源和Rows之间应用另一个ParDo,将源产生的元素手动转换为SqlTransform
  • 使用Beam的Schema框架(例如检出PCollection.setSchema()方法),该框架允许Beam SQL自动将输入元素转换为Rows;