我使用标准的Bonobo编写器进行文件输出(CsvWriter等)。
如果这些传递了绝对路径(' /data/output.csv'),他们会认为它是相对的,因此找不到触发资源'错误。
在Docker容器中使用Bonobo时尤其如此,因为它是写入绝对路径(卷装入点)的常用模式。
让Bonobo接受绝对路径的最佳方式是什么?
答案 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。我认为正确的行为是提出例外。