ETL&;解析云数据流中的CSV文件
我不熟悉云数据流和Java,所以我希望这是一个正确的问题 我有一个csv文件,有n个列和行,可以是字符串、整数或时间戳。是否需要为每个列创建新的PCollection 我在示例中找到的大多数文档都是这样的: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”); 但
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);
}