【问题标题】:How do I use an AutoValue data type for my PCollection in Apache Beam?如何在 Apache Beam 中为我的 PCollection 使用 AutoValue 数据类型?
【发布时间】:2020-06-24 01:28:23
【问题描述】:

我想在我的 PCollection 中使用我的 AutoValue 数据类作为对象类型,但是我在使用自动编码器时遇到了问题:

@AutoValue
public abstract class MyPersonClass {
  public abstract String getName();
  public abstract Integer getAge();
  public abstract Float getHeight();

  public static MyPersonClass create(String name, Integer age, Float height) {
    return new AutoValue_MyPersonClass(name, age, height);
  }
}

每当我使用它时,我都会从 Beam 尝试选择编码器时收到错误消息。我不想为它定义自己的编码器。

如何使用编码器来推断我的 AutoValue 类的架构?或者可以自动推断出不同的编码器吗?

【问题讨论】:

    标签: java google-cloud-dataflow apache-beam


    【解决方案1】:

    Beam 有一个实用程序可以自动推断不同数据类的模式,包括 Java Bean、带有 Getter 和 Setter 的 Bean、Avro 记录、协议缓冲区和 AutoValue 类。

    您只需使用适当的SchemaProvider (see the SchemaProvider javadoc and discover subclasses there) 添加DefaultSchema 注释。

    此注释适用于 AutoValue 构建器,因此如果您使用 AutoValue.Builder 模式,则不需要其他任何东西

    如果您改用create 函数,就像在这种情况下,您可以添加SchemaCreate 注释,如下所示:

    import org.apache.beam.sdk.schemas.AutoValueSchema;
    import org.apache.beam.sdk.schemas.annotations.DefaultSchema;
    import org.apache.beam.sdk.schemas.annotations.SchemaCreate;
    
    @DefaultSchema(AutoValueSchema.class)
    @AutoValue
    public abstract class MyPersonClass {
      public abstract String getName();
      public abstract Integer getAge();
      public abstract Float getHeight();
    
      @SchemaCreate
      public static MyPersonClass create(String name, Integer age, Float height) {
        return new AutoValue_MyPersonClass(name, age, height);
      }
    }
    

    最后,如果你不能自己修改类(可能是因为你不拥有源 包含 AutoValue 类的代码),您可以手动注册它,如下所示:

    pipeline.getSchemaRegistry().registerSchemaProvider(
        MyPersonClass.class, new AutoValueSchema());
    

    【讨论】:

    • 编码器存在重大问题 - 请参阅 BEAM-1891。
    • 感谢@AlessandroSantini 提供此参考。我能够找出我在上面作为单独答案提到的一个约束。您指的还有其他问题吗?
    【解决方案2】:

    接受的答案非常好。

    我的 2 美分,在 AutoValueSchema 中存在一个约束,ReflectionUtils#isGtter,它期望 AutoValue 的字段遵循 get* 约定。 如果您遵循将 getter 命名为 field() 而不是 getField() 的约定,则 AutoValueSchema 不会将它们注册为实际的 getter 方法,因此不会作为用于创建模式的属性。 (最后一点对我来说有点模糊,因为我不确定通过 getter 识别属性的完整流程,必须更详细地阅读源代码)。

    因此,到目前为止,您必须将所有 AutoValue getter 命名为 get*() 才能正确使用 Beam 的 AutoValueSchema。

    有关详细信息,请参阅:https://github.com/apache/beam/pull/7334https://github.com/apache/beam/pull/7334#issuecomment-453560743

    【讨论】:

      猜你喜欢
      • 2022-12-31
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多