我正在使用标准的倭黑猩猩编写器进行文件输出(CsvWriter等)。
如果这些被传递一个绝对路径('/data/output.csv'),它们将假定它是相对的,从而触发"找不到资源"错误。
在 Docker 容器中使用 Bonobo 时,这尤其是一个问题,因为写入绝对路径(卷挂载点)是一种常见的模式。
让倭黑猩猩接受绝对路径的最佳方法是什么?
默认情况下,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"文件系统以指向"/data"(或指向os.environ.get('DATA_PATH', '/data')
,甚至更好)。然后从这个抽象的文件系统中打开一个本地文件。
希望对您有所帮助!
附言如果您为读者提供绝对路径,它会错误地忽略前导"/",这是一个错误,跟踪为 #211。我认为,正确的行为是提出一个例外。