将CSV文件从GCS导入BigQuery

时间:2017-07-14 14:38:48

标签: google-cloud-dataflow

我正在试图弄清楚如何将GCS中的CSV文件加载到BigQuery中。管道如下:

    // Create the pipeline
    Pipeline p = Pipeline.create(options);

    // Create the PCollection from csv
    PCollection<String> lines = p.apply(TextIO.read().from("gs://impression_tst_data/incoming_data.csv"));


    // Transform into TableRow
    PCollection<TableRow> row = lines.apply(ParDo.of(new StringToRowConverter()));


    // Write table to BigQuery
    row.apply(BigQueryIO.<TableRow>writeTableRows()
            .to(“project_id:dataset.table”)
            .withSchema(getSchema())
            .withWriteDisposition(WriteDisposition.WRITE_APPEND)
            .withCreateDisposition(CreateDisposition.CREATE_IF_NEEDED));

这是我在ParDo中使用的StringToRowConverter类来创建TableRow PCollection:

// StringToRowConverter
static class StringToRowConverter extends DoFn<String, TableRow> {
    @ProcessElement
    public void processElement(ProcessContext c) {
        c.output(new TableRow().set("string_field", c.element()));
    }
}

查看暂存文件,看起来这样会创建一个JSON的TableRows,它将csv集中到一个名为“string_field”的列中。如果我没有在模式中定义string_field,则作业失败。当我确定string_field时,它会将CSV的每一行写入列中,并将架构中定义的所有其他列留空。我知道这是预期的行为。

所以我的问题:如何获取此JSON输出并将其写入模式?下面的示例输出和架构......

"string_field": "6/26/17 21:28,Dave Smith,1 Learning Drive,867-5309,etc"}

架构:

static TableSchema getSchema() {
            return new TableSchema().setFields(new ArrayList<TableFieldSchema>() {
                // Compose the list of TableFieldSchema from tableSchema.
                {
                    add(new TableFieldSchema().setName("Event_Time").setType("TIMESTAMP"));
                    add(new TableFieldSchema().setName("Name").setType("STRING"));
                    add(new TableFieldSchema().setName("Address").setType("STRING"));
                    add(new TableFieldSchema().setName("Phone").setType("STRING"));
                    add(new TableFieldSchema().setName("etc").setType("STRING"));
                }
            });
        }

有没有比使用StringToRowConverter更好的方法呢?

我需要使用ParDo创建TableRow PCollection才能将其写入BQ。但是,我无法找到如何接受CSV PCollection,转换为TableRow并将其写出来的可靠示例。

是的,我是一个努力在这里学习的菜鸟。我希望有人可以用一个片段来帮助我,或者以最简单的方式指出我正确的方向。提前谢谢。

1 个答案:

答案 0 :(得分:1)

StringToRowConverter DoFn中的代码应解析字符串并生成包含多个字段的TableRow。由于每一行都以逗号分隔,这可能涉及在逗号上拆分字符串,然后使用您对列顺序的了解来执行以下操作:

String inputLine = c.element();

// May need to make the line parsing more robust, depending on your
// files. Look at how to parse rows of a CSV using Java.
String[] split = inputLine.split(',');

// Also, you may need to handle errors such as not enough columns, etc.

TableRow output = new TableRow();
output.set("Event_Time", split[0]); // may want to parse the string
output.set("Name", split[1]);
...
c.output(output);