数据流管道中的访问文件

时间:2019-01-02 12:06:55

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

我想在管道启动之前将某些文件下载到临时位置。要在ParDo功能中读取的.mmdb文件。这些文件存储在Google Storage上,但是使用.mmdb文件的方法需要它们是一个File(java.io)对象。

如果我将其包含在--filesToStage中,则它们可用作InputStream 里面的拉链。我想将它们作为文件而不是InputStream进行访问。 实现此目标的最佳方法是什么?

我目前正在ParDo设置程序内的工作程序的临时文件夹中下载文件。

2 个答案:

答案 0 :(得分:1)

这是一个非常广泛和高水平的问题。答案取决于您使用文件的逻辑。 File代表file on a filesystem,因此,如果您有一个要求输入为File实例的组件,那么将其本地写入临时文件夹是正确的做法。在这种情况下,Beam无法提供更好的抽象。

但是,我建议您考虑更新当前处理Files的逻辑以接受其他类型的输入。您可能会遇到由于缺乏关注点分离和紧密耦合而导致的问题。也就是说,您有一个包含File,打开它,在打开时处理错误,读取它,从中解析数据,甚至验证和处理数据的组件。所有这些都是单独的关注点,可能应该由单独的组件处理,您可以在需要时将其组合并替换在一起,例如:

  • 知道如何处理文件系统并将路径转换为字节流的类;
  • 类似的类,知道如何处理通过http获取文件(例如GCS用例)并将其转换为字节流;
  • 知道如何将字节流解析为数据的组件;
  • 处理已解析数据的组件;
  • 其他事物可能可以生活在任何地方;

通过这种方式,您可以轻松地为组件实现其他任何来源,分别进行编写和测试。

例如,您可以将逻辑实现为2个连接的PCollections,其中一个将直接从GCS位置读取,解析文本行,并在实际的业务逻辑中进行处理,然后再将其与其他PCollection

答案 1 :(得分:0)

我想我了解您正在/正在尝试做的事情,而我也一直想这样做。

这对我有用(在DoFn的setup()方法中):

 if(not FileSystems.exists(local_db_location) ):
        with FileSystems.open(  self._cloud_database_loc ) as af:
            with FileSystems.create(local_db_location) as local_file:
                try:
                    shutil.copyfileobj(af,local_file,length=131072)
                except:
                    raise
    else:
        #DB exists