我正在尝试在PCollection<Object>
上应用SQLTransform。这里,CustomSource转换在运行时生成一个Pojo。因此,在编译时不知道运行SQLTransform的对象的类型。
Pipeline p = Pipeline.create(options);
PCollection<Object> objs = p.apply(new CustomSource());
Schema type = Schema.builder().addInt32Field("c1").addStringField("c2").addDoubleField("c3").build();
PCollectionTuple.of(new TupleTag<>("somedata"), objs).apply(SqlTransform.query("SELECT c1 FROM somedata"))
.setSchema(type, SerializableFunctions.identity(), SerializableFunctions.identity());
p.run().waitUntilFinish();
我已将SQLTransform
提供给setSchema
的架构,但是我收到了一个错误
java.lang.IllegalStateException: Cannot call getSchema when there is no schema
at org.apache.beam.sdk.values.PCollection.getSchema(PCollection.java:328)
PCollection.java:328
at org.apache.beam.sdk.extensions.sql.impl.schema.BeamPCollectionTable.<init>(BeamPCollectionTable.java:34)
是否可以在运行时生成Pojo对象并通过向转换提供模式信息来在它们上运行sqltransforms?
这是CustomSource类供参考:
import java.util.HashMap;
import java.util.Map;
import com.beaconinside.messages.PojoGenerator;
import org.apache.beam.sdk.coders.StringUtf8Coder;
import org.apache.beam.sdk.transforms.Create;
import org.apache.beam.sdk.transforms.PTransform;
import org.apache.beam.sdk.values.PBegin;
import org.apache.beam.sdk.values.PCollection;
import javassist.CannotCompileException;
import javassist.NotFoundException;
public class CustomSource extends PTransform<PBegin, PCollection<Object>> {
Map<String, Class<?>> props;
Class<?> clazz;
String data = "{\"c1\": 1, \"c2\": \"row\", \"c3\": 2.0}";
public CustomSource() throws NotFoundException, CannotCompileException {
props = new HashMap<String, Class<?>>();
props.put("c1", Integer.class);
props.put("c2", String.class);
props.put("c3", Double.class);
clazz = PojoGenerator.generate("net.javaforge.blog.javassist.PojoGenerated", props);
}
@Override
public PCollection<Object> expand(PBegin input) {
return input.apply(Create.of(data)).setCoder(StringUtf8Coder.of()).apply(new SensorSource(clazz, props));
// return input.apply(Create.of(data));
}
}
答案 0 :(得分:1)
我认为您的setSchema只是从SQLTransform
输出的PCollection的设置模式。您还应该在PCollection<Object> objs
上设置架构。
答案 1 :(得分:0)
以上答案是正确的,PCollection<Object>
也应该调用setSchema
来定义输入数据模式和行对象转换函数。如果您有多个PCollection来构建PCollectionTuple,则PCollections应该分别调用setSchema。 PCollectionTuple不需要调用setSchema,因为可以从SQL命令推断输出模式。
答案 2 :(得分:0)
按如下所示使用setRowSchema
PCollection<Row> testApps = PBegin.in(p).apply(Create.of(row1,row2,row3).withCoder(RowCoder.of(appSchema)))
.setRowSchema(appSchema);