ETL&;解析云数据流中的CSV文件

ETL&;解析云数据流中的CSV文件,csv,google-cloud-dataflow,Csv,Google Cloud Dataflow,我不熟悉云数据流和Java,所以我希望这是一个正确的问题 我有一个csv文件,有n个列和行,可以是字符串、整数或时间戳。是否需要为每个列创建新的PCollection 我在示例中找到的大多数文档都是这样的: PCollection<String> data = p.apply(TextIO.Read.from("gs://abc/def.csv")); PCollection data=p.apply(TextIO.Read.from(“gs://abc/def.csv”); 但

我不熟悉云数据流和Java,所以我希望这是一个正确的问题

我有一个csv文件,有n个列和行,可以是字符串、整数或时间戳。是否需要为每个列创建新的PCollection

我在示例中找到的大多数文档都是这样的:

PCollection<String> data = p.apply(TextIO.Read.from("gs://abc/def.csv"));
PCollection data=p.apply(TextIO.Read.from(“gs://abc/def.csv”);

但对我来说,将整个csv文件作为字符串导入是没有意义的。我在这里遗漏了什么?我应该如何设置我的PCollections?

此示例将创建一个集合,其中文件中每行包含1个
字符串,例如,如果文件为:

Alex,28,111-222-3344
Sam,30,555-666-7788
Drew,19,123-45-6789
然后,该集合将逻辑上包含
“Alex,28111-222-3344”
“Sam,30555-666-7788”
,以及
“Drew,19123-45-6789”
。您可以通过
ParDo
maplements
转换管道化集合,在Java中应用进一步的解析代码,例如:

class User {
    public String name;
    public int age;
    public String phone;
}

PCollection<String> lines = p.apply(TextIO.Read.from("gs://abc/def.csv"));
PCollection<User> users = lines.apply(MapElements.via((String line) -> {
    User user = new User();
    String[] parts = line.split(",");
    user.name = parts[0];
    user.age = Integer.parseInt(parts[1]);
    user.phone = parts[2];
    return user;
}).withOutputType(new TypeDescriptor<User>() {});)
类用户{
公共字符串名称;
公共信息;
公用串电话;
}
PCollection line=p.apply(TextIO.Read.from(“gs://abc/def.csv”);
PCollection users=lines.apply(MapElements.via)((字符串行)->{
用户=新用户();
String[]parts=line.split(“,”);
user.name=零件[0];
user.age=Integer.parseInt(部分[1]);
user.phone=零件[2];
返回用户;
}).withOutputType(新类型描述符(){});)
如果行数据如下所示,则String.split没有意义:

a、 b,c,“我们有一个包含逗号的字符串”,d,e

处理csv数据的一种方法是导入csv库:

        <dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>3.7</version>
        </dependency>

谢谢@jkff,我现在来看看。我会使用String[]parts=line.split(,((?=([^\“]*\”[^\“]*\”*[^\“]*$)来解释额外的逗号和引号。这很好,谢谢。有没有更健壮的方法来处理具有意外列顺序的CSV?@Eugene在您的示例中是否可以使用
line.apply(ParDo.of(new CreateUser())
和在DoFn processElement方法中编写转换逻辑?以及withOutputType()的用途。ParDo也可以工作,只是不够简洁。withOutputType是由于与Java类型擦除相关的技术原因而需要的,如果省略它,在这种情况下编码器推断将不起作用。
        <dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>3.7</version>
        </dependency>
public void processElement(ProcessContext c) throws IOException {
    String line = c.element();
    CSVParser csvParser = new CSVParser();
    String[] parts = csvParser.parseLine(line);
}