使用Scio将SCollection从textFile放入BigQuery

时间:2019-01-29 13:34:31

标签: scala spotify-scio

我用textFile阅读了一些文档,并对单个单词做了flatMap,为每个单词添加了一些额外的信息:

val col = sc.textFile(args.getOrElse("input","documents/*"))
    .flatMap(_.split("\\s+").filter(_.nonEmpty))
val mapped = col.map(t => t + ": " + extraInformation())

我目前正在轻松地将其保存为文本

mapped.saveAsTextFile(args.getOrElse("output", "results"))

但是我不知道如何将地图保存到BigQuery架构。我见过的所有示例都从BigQuery创建了初始Scollection,然后将其保存到另一个表中,因此初始集合是[TableRow]而不是[String]

这里正确的方法是什么?我应该研究如何将我的数据转换为Big Query接受的一种收集方式吗?还是我应该尝试进一步研究如何将这些纯文本直接放入表格中?

2 个答案:

答案 0 :(得分:3)

我建议在案例类上使用@BigQueryType.toTable批注,例如:

import com.spotify.scio.bigquery._

object MyScioJob {

  @BigQueryType.toTable
  case class WordAnnotated(word: String, extraInformation: String)


  def main(args: Array[String]): Unit = {
    // ...job setup logic

    sc.textFile(args.getOrElse("input","documents/*"))
      .flatMap(_.split("\\s+").filter(_.nonEmpty))
      .map(t => WordAnnotated(t, extraInformation())
      .saveAsTypedBigQuery("myProject:myDataset.myTable")
  }
}

有关Scio wiki的更多信息。

答案 1 :(得分:0)

要写入BigQuery,您需要定义一个TableSchema:

public static final TableSchema BQ_TABLE_SCHEMA = new TableSchema();
public static final List<TableFieldSchema> BQ_FIELDS;

static {
    TableFieldSchema string_field = new TableFieldSchema()
            .setName("string_field")
            .setType(FieldType.STRING.toString())
            .setMode(FieldMode.NULLABLE.toString());

    BQ_FIELDS = Lists.newArrayList(
            string_field
    );

    BQ_TABLE_SCHEMA.setFields(BQ_FIELDS);
}

然后您需要将String转换为TableRow对象:

.apply("ConvertToTableRow", ParDo.of(new DoFn<String, TableRow>() {
                    @ProcessElement
                    public void processElement(ProcessContext c) {
                        c.output(new TableRow().set("string_field", c.element()));
                    }
                }))
.apply("InsertTableRowsToBigQuery",
                        BigQueryIO.writeTableRows().to("project_id:dataset_name.table_name")
                                .withSchema(BQ_TABLE_SCHEMA)
                                .withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_IF_NEEDED)
                                .withWriteDisposition(BigQueryIO.Write.WriteDisposition.WRITE_APPEND))
                .getFailedInserts();

您也可以看一下Java中的此示例,它与Scio中需要完成的操作非常相似:https://github.com/apache/beam/blob/master/examples/java/src/main/java/org/apache/beam/examples/complete/StreamingWordExtract.java#L78