使用Bonobo写入绝对文件路径

时间:2018-03-22 12:08:44

标签: python etl bonobo-etl

我使用标准的Bonobo编写器进行文件输出(CsvWriter等)。

如果这些传递了绝对路径(' /data/output.csv'),他们会认为它是相对的,因此找不到触发资源'错误。

在Docker容器中使用Bonobo时尤其如此,因为它是写入绝对路径(卷装入点)的常用模式。

让Bonobo接受绝对路径的最佳方式是什么?

1 个答案:

答案 0 :(得分:2)

默认情况下,bonobo定义一个名为fs的文件系统“service”,指向您的本地目录。此服务是bonobo核心中提供的所有读者和作者使用的默认文件系统。

我会避免将文件位置视为绝对位置,因为这意味着您使软件依赖于特定的文件系统结构。相反,请考虑“文件容器”(恰好是本地文件系统上的目录,但这是一个实现细节),并考虑如何在每个“文件容器”中组织文件。

Bonobo使用PyFilesystem2来抽象这些容器。目标是不对系统进行任何硬编码,而是允许在运行时轻松配置数据管道。

您可以定义更多文件系统服务,以逻辑方式绑定某些业务逻辑的不同路径。在您的情况下,假设/data是“数据”的位置,您可以定义自己的文件系统服务,映射到此目录:

import bonobo

def get_services():
    return {
        'fs.data': bonobo.open_fs('/data'),
    }

def get_graph():
    return bonobo.Graph(
        bonobo.CsvReader('input.csv', fs='fs.data'),
        ... # etc
    )

...

if __name__ == '__main__':
    bonobo.run(get_graph(), services=get_services())

这样可以很好地分离关注点,并且可以大大提高转换的可移植性。

当然,您也可以覆盖默认文件系统:

import bonobo

def get_services():
    return {
        'fs': bonobo.open_fs('/data'),
    }

您可以定义多个文件系统,有人可能会:

import bonobo

def get_services():
    return {
        'fs.input': bonobo.open_fs('/input_data'),
        'fs.output': bonobo.open_fs('/output_data'),
    }

通过将服务定义与实际图形实现分开,您将获得根据周围环境(开发笔记本电脑,生产,计算集群......)切换文件系统的能力。例如,它允许使用开发盒上的本地文件,并在生产时切换到AWS S3存储。

更好的方法是从环境中读取默认值。

要在docker容器中正常工作,只需将“数据”文件系统定义为指向“/ data”(或os.environ.get('DATA_PATH', '/data'),甚至更好)。然后从这个抽象的文件系统中打开一个本地文件。

希望有所帮助!

P.S。事实上,如果你提供一个读者的绝对路径它加入它错误地忽略前导“/”是一个错误,跟踪为#211。我认为正确的行为是提出例外。