2

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

如果这些被传递了一个绝对路径('/data/output.csv'),他们将假定它是相对的,从而触发'资源未找到'错误。

这在 Docker 容器中使用 Bonobo 时尤其会出现问题,因为写入绝对路径是卷安装点的常见模式。

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

4

1 回答 1

3

默认情况下,定义一个称为指向本地目录bonobo的文件系统“服务” 。fs该服务是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'),甚至更好)。然后从这个抽象的文件系统中打开一个本地文件。

希望有帮助!

PS 如果您向阅读器提供绝对路径,它会错误地连接它而忽略前导的“/”,这是一个错误,跟踪为#211。我认为正确的行为是引发异常。

于 2018-03-22T19:10:44.383 回答