Python 使用BO etl加载多个文件

Python 使用BO etl加载多个文件,python,bonobo-etl,Python,Bonobo Etl,我是bonobo etl的新手,我正在尝试编写一个一次加载多个文件的作业,但我无法让CsvReader使用@use\u context\u处理器注释。我的代码片段: def input_file(self, context): yield 'test1.csv' yield 'test2.csv' yield 'test3.csv' @use_context_processor(input_file) def extract(f): return bonobo.

我是bonobo etl的新手,我正在尝试编写一个一次加载多个文件的作业,但我无法让CsvReader使用
@use\u context\u处理器
注释。我的代码片段:

def input_file(self, context):
    yield 'test1.csv'
    yield 'test2.csv'
    yield 'test3.csv'

@use_context_processor(input_file)
def extract(f):
    return bonobo.CsvReader(path=f,delimiter='|')

def load(*args):
    print(*args)

def get_graph(**options):
    graph = bonobo.Graph()
    graph.add_chain(extract,load)
    return graph
当我运行作业时,我得到的是类似于
的内容,而不是CSV的行

如果我像
graph.add\u chain(bonobo.CsvReader(path='test1.csv',delimiter='|'),load)那样硬编码读取器
,它会工作

任何帮助都将不胜感激


谢谢。

由于bonobo.CsvReader不支持(尚未)从输入流读取文件名,因此需要使用自定义读取器

以下是一个在我拥有的一组CSV上适用的解决方案:

import bonobo
import bonobo.config
import bonobo.util
import glob
import csv

@bonobo.config.use_context
def read_multi_csv(context, name):
    with open(name) as f:
        reader = csv.reader(f, delimiter=';')
        headers = next(reader)
        if not context.output_type:
            context.set_output_fields(headers)
        for row in reader:
            yield tuple(row)

def get_graph(**options):
    graph = bonobo.Graph()

    graph.add_chain(
      glob.glob('prenoms_*.csv'),
      read_multi_csv,
      bonobo.PrettyPrinter(),
    )

    return graph


if __name__ == '__main__':
    with bonobo.parse_args() as options:
        bonobo.run(get_graph(**options))
按阅读顺序,对该代码段的注释不多:

  • use\u context
    decorator将向转换调用注入节点执行上下文,允许使用
    。使用第一个csv头设置\u output\u字段(…)
  • 其他csv头被忽略,在我的例子中,它们都是相同的。对于您自己的案例,您可能需要稍微复杂一点的逻辑
  • 然后,我们使用
    glob.glob
    (在我的例子中,流将包含:prenoms_2004.csv prenoms_2005.csv…prenoms_2011.csv prenoms_2012.csv)在一个
    bonobo.Graph
    实例中生成文件名,并将其传递给我们的自定义读取器,该读取器将为每个文件调用一次,打开它,并生成它的行
希望有帮助